我正在浏览网页,然后我发现了这个:
var i, len;
for(i = 0, len = array.length; i < len; i++) {
//...
}
我的第一反应是:
- 他为什么要那样做?(一定有更好的原因)
- 值得吗?(我认为肯定值得,否则他不会这样做)
普通循环(不缓存长度的循环)每次都会检查array.length
吗?
我正在浏览网页,然后我发现了这个:
var i, len;
for(i = 0, len = array.length; i < len; i++) {
//...
}
我的第一反应是:
普通循环(不缓存长度的循环)每次都会检查array.length
吗?
一个由三个部分组成的循环按照以下方式执行:
for (A; B; C)
A - Executed before the enumeration
B - condition to test
C - expression after each enumeration (so, not if B evaluated to false)
所以,如果使用for(var i=0; i<array.length; i++)
这种方式构建数组,则在每次枚举时会检查数组的.length
属性。为了微观优化,将数组长度存储在临时变量中是有效的(另请参见:JavaScript中循环遍历数组的最快方法是什么?)。for (var i=0; i<array.length; i++) { ... }
等效:var i = 0;
while (i < array.length) {
...
i++;
}
B
,每次迭代都需要在对象/数组上进行一次查找,这比在本地范围内进行查找要慢。如果可以在本地范围内找到某些东西,那么它总是查找的最快方式,这就是为什么您会使用var foo =
将长度存储在当前范围中的原因。 - jAndy是的,它每次都会检查数组的长度,但如果我们不想为增加的数组运行循环,则可以使用forEach方法。
forEach是一个JavaScript内置方法,类似于for循环,但forEach仅遍历循环开始之前的数组元素。
让我们从以下片段中了解:
array = [1,2,3,4]
for(i=0;i<=array.length;i++){
console.log(array[i]);
array.push(array[i]+1);
}
输出如下: 1 2 3 4 5 6 ...等等(无限),同时每次都检查array.length
让我们使用forEach方法来检查
array = [1,2,3,4]
array.forEach((element) => {
console.log(element);
array.push(element+1);
})
console.log("array elements after loop",array);
它只处理在迭代开始之前存在于数组中的4个元素。
但是在forEach情况下,如果我们从数组中弹出元素,它将影响数组长度。
让我们通过一个例子来看看:
array = [1,2,3,4]
array.forEach((element) => {
console.log(element);
array.pop()
})
console.log("array elements after loop",array);
var initialLength = items.length;
for(var i=0; i<initialLength; ++i) {
items.push(items[i]);
}
如果在循环之前不保存长度,那么数组的长度将会不断增加,直到浏览器崩溃/终止。
除此之外,正如其他人所说,这会轻微地影响性能。我不会因为“过早优化是万恶之源”而养成这种习惯。此外,如果您在循环期间更改数组的大小,则可能会破坏代码。例如,如果您在循环期间从数组中删除元素但仍然将 i 与先前的数组大小进行比较,则循环将尝试访问新大小之外的元素。