使用 array.length 时无限循环

Endless for loop when using array.length

偶然遇到这个。当我将 array.length 存储在变量中并使用 operator <= 应用于 for 循环条件时,循环工作正常但是当我将 array.length 与相同的运算符一起使用时,它变得无限。

function map(array, callback) {
  let k =array.length;
   for(let i= 1; i<=k; i++)
     {
      array[i] = callback(array[i]);
     }

    return array;
}
console.log(map([1, 2, 3], addTwo));

这按预期工作。但是当我使用这个

   function map(array, callback) {

    for(let i= 1; i<=array.length; i++)
     {

     array[i] = callback(array[i]);
     }

    return array;
    }
     console.log(map([1, 2, 3], addTwo));

当然i=0; i<array.length;是方法。不过很好奇里面到底发生了什么

在第一种情况下,带有长度的变量不会改变,但在第二种情况下,你直接取长度并改变。

let k = array.length;

保持长度直到迭代器到达大于 k 的索引。

另一个

for (let i = 1; i <= array.length; i++)
//                 ^

取实际长度,当索引与长度进行比较时,在原始数组末尾的每次调用都会为数组添加一个索引。

你可以很容易地看到如果你在其中添加一个 console.log 会发生什么:

let addTwo = x => x + 2

function map(array, callback) {
  for (let i = 1; i <= array.length; i++) {
    console.log(i, array.length)  // <-- print out i and the length of the array
    array[i] = callback(array[i]);
    if(i==5)  // <-- so we do not run out of memory
     return false
  }
  return array;
}
console.log(map([1, 2, 3], addTwo));

最重要的是,只要 i 小于或等于 array.lengthfor loop 就应该继续,但同时一旦 i 达到数组的实际长度我们继续增加bothi 通过 i++array.length 通过 array[i] = callback(array[i]); 所以看不到尽头。