我对JS很新,并且认识到长度被视为属性。但我收到一条评论,不在循环中使用str.length:
for (i=0; i<str.length; i++){...}
VS
var len = str.length;
for (i=0; i<len; i++){...}
现在,我知道str.length()是Java中的常量时间操作,因为长度存储为String类中的字段。但话说回来,字符串在Java中是不可变的。 我不确定JS字符串。 str.length是否也保证了JS中的常量时间?无法在网络上的任何地方找到这个。
答案 0 :(得分:13)
答案 1 :(得分:1)
str.length
是否也保证了JS的常量时间?
不,实际上JavaScript中没有运行时性能或复杂性保证。
然而,是的,可以预期可以在恒定时间内访问它,在访问时没有动态线性时间长度计算。 ECMAScript规范还将String .length
property描述为不可变的,并在构造字符串时初始化。
答案 2 :(得分:1)
在任何具有不连续字符串的语言中,无论是Java,JavaScript,C#还是其他语言,语言的创建者都不会提供一个非常糟糕的时间&#34; &#34;长度&#34;字符串的操作。
由于字符串是不可变的,因此它的长度不能改变,因此所需要的只是在字符串对象内的某些字段中创建字符串的长度,并在调用&#34; length&#34;时返回它。属性格式/方法。
答案 3 :(得分:0)
长度是一个实例属性,它是一个恒定的时间
它必须实现一个给定长度的字符串,该字符串表示为连续的,以零结尾的jschars数组。它通过显式存储长度和指向零端接数组
的指针来实现
显式存储是这里的指标,它是恒定的时间。
阅读How Strings Are Implemented In SpiderMonkey 有关Firefox如何实现字符串的更多信息。
答案 4 :(得分:0)
这个问题似乎得到了很好的回答,但这是另一个2¢可能会有所帮助。
如果字符串被循环内部长度不同的字符覆盖,则使用string.length
会导致for循环出现意外行为,例如:
var k = "abcabcabc";
for(var i=0; i<k.length; i++){
k=k.slice(0,-1);
console.log(k);
}
将记录“abcabcab”,“abcabca”,...,“abca”然后停止,因为长度正在变化。
当然,这可能是有意的,在这种情况下去吧(虽然可以说你应该使用while循环)。
答案 5 :(得分:-1)
W3Schools recommends:
l = arr.length;
for (i = 0; i < l; i++) {..}
而不是:
for (i = 0; i < arr.length; i++) {...}
声称:
击><击>每次循环迭代时,错误的代码都会访问数组的length属性。
更好的代码访问循环外的length属性,并使循环运行得更快。
因为w3schools是邪恶的,让我引用另一个来源(Writing Efficient JavaScript - Nicholas C. Zakas)。
...从这些信息中获取的重要教训是始终将经常访问的值存储在局部变量中。请考虑以下代码:
function process(data){
if (data.count > 0){
for (var i=0; i < data.count; i++){
processData(data.item[i]);
}
}
}
...如果此值存储在局部变量中,函数将运行得更快 然后从那里访问:
function process(data){
var count = data.count;
if (count > 0){
for (var i=0; i < count; i++){
processData(data.item[i]);
}
}
}
来自here:
大多数JavaScript引擎使用类似字典的数据结构作为对象属性的存储 - 每个属性访问都需要动态查找来解析属性在内存中的位置。这种方法使得访问JavaScript的属性通常比访问Java和Smalltalk等编程语言中的实例变量要慢得多。
通常,一些(或大多数)JavaScript引擎使用优化技术来改进this one之类的V8属性访问时间。
此外,JavaScript字符串对象可能具有不同的性质,因为您无法动态地向其添加属性。 (这使得动态查找变得不必要..我猜)
对于string.length
,请使用两个代码段中的任何一个。但对于进行计算的其他对象类型或属性,则必须首先对代码性能进行基准测试(或者只将值存储在局部变量中)。