为什么 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
永远不会是 false
: Endless 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"]
...
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
永远不会是 false
: Endless 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"]
...