为什么 splice 在这个 for 循环中不起作用?

Why isn't splice working in this for loop?

var arr = ['apples','oranges','pears','grapes'];

for (var i=0; i<arr.length; i++) {
  if (arr[i] == 'pears') {
    arr.splice(i,0,'limes');
  }
}

当我在 jsfiddle 中尝试 运行 时,页面冻结。如果我使用特定索引代替 i (arr.splice(2,0,'limes')) 或者如果我尝试删除项目 (arr.splice(2,1)),jsfiddle 也会冻结。如果我在没有 for 循环的情况下执行此操作,而是选择一个特定的索引,它将起作用。这里出了什么问题?有什么方法可以让 splice 在 for 循环中工作(用于添加,而不是删除项目)?

此外,当我将 FreeCodeCamp 的编辑器与此代码一起使用时,它不会冻结,但会返回原始数组,就好像从未在其上使用过 splice 一样。但是,如果我为它分配一个变量(for 循环中的 var rem = arr.splice(i,1)),它会 returns 删除的项目而不实际修改数组本身(数组保持完全相同)。

你有一个无限循环。您在梨之前添加了一个新元素,而不是将其删除。所以下一次迭代会再次给你梨。如果那是您的意图,只需添加一个 break 语句。如果你想替换元素 pear 可以使用下面的函数。

From MDN

array.splice(start, deleteCount[, item1[, item2[, ...]]])

您可以看到您没有删除任何内容,而是在索引 i 之前(即在 pears 之前)添加了一个新元素。

var arr = ['apples','oranges','pears','grapes'];

for (var i=0; i<arr.length; i++) {
  if (arr[i] == 'pears') {
    arr.splice(i,1,'limes');
 
  }
}

console.log(arr);

这就是 for 循环的工作方式:

for (var i=0; i < arr.length; i++);

i=0;0 初始化 i;然后,在每次迭代开始时检查此条件 i < arr.length 如果它是 true 则执行下一次迭代,否则退出循环。在每次迭代结束时 i++ 递增 i.

由于 arr.splice(i,0,'limes') 改变数组并在位置 i 添加一个元素,它将把值 pears 推到下一个索引。因此,if (arr[i] == 'pears') 将始终是 true 而此条件 i < arr.length 永远不会是 falseEndless for ...

arr.splice(i,0,'limes'); 

将在 'pears' 元素 之前 注入 'limes' 元素, 有效地将它移动一个位置到数组的末尾, 所以在下一次迭代中,您的代码将再次点击 'pears', 然后在它前面再注入一个'limes'等等。

您可以通过添加

轻松地将其可视化
console.log(arr);

在你的 if 块之后,这将导致如下输出:

    ["apples", "oranges", "limes", "pears", "grapes"]
    ["apples", "oranges", "limes", "limes", "pears", "grapes"]
    ["apples", "oranges", "limes", "limes", "limes", "pears", "grapes"]
    ["apples", "oranges", "limes", "limes", "limes", "limes", "pears","grapes"]
    ...