为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 javascript forEach 循环不使用 splice 迭代完整数组

为什么 javascript forEach 循环不使用 splice 迭代完整数组

忽然笑 2021-12-02 15:41:50
我在玩 javascript.splice()和.forEach()方法,代码工作正常,但没有按预期提供输出。问题是.forEach()运行半阵列然后退出。我期望的输出是[['Apple'],['Banana'],['Mango'],['Pomegranate']]但输出是[['Apple'],['Banana']]我无法弄清楚它为什么会这样。从mdn它说该 .splice()方法更新数组的长度属性。那么它应该可以正常工作。有什么办法可以让它像预期的那样工作。出于某种原因,我只是不想使用.map()或任何其他功能。const fruits = ['Apple', 'Banana', 'Mango', 'Pomegranate']const fruitsList = []function removeArrayItem(item,index){    let fruit = fruits.splice(0,1)    fruitsList.push(fruit)}fruits.forEach(removeArrayItem)console.log(fruitsList)
查看完整描述

3 回答

?
慕标琳琳

TA贡献1830条经验 获得超9个赞

正如MDN 文档中非常清楚地描述的那样,该.forEach()方法在迭代开始之前确定将涉及的元素。


如果元素被添加到数组中,它们将不会被包含在迭代中。如果删除元素,则将跳过后续元素。基本上有一个用于选择每个元素的内部索引,因此如果数组变短,则无法相应地调整该索引。


最重要的是,您编写的代码使得.forEach()回调忽略它的参数。它总是只去掉fruits数组的第一个元素。因此,在第一次迭代时,您会得到“Apple”,而数组现在只有三个元素。下一个迭代的元素将是“Mango”,而不是“Banana”,但因为代码没有注意item你得到源数组的第一个新元素。之后,数组只有两个项目,因此迭代终止。


您将看到与此代码完全相同的效果,这可能更清晰,因为该机制是可见的:


const fruits = ['Apple', 'Banana', 'Mango', 'Pomegranate']

const fruitsList = []


for (let index = 0, len = fruits.length; index < len; index++) {

  if (index in fruits) {

      let fruit = fruits.splice(0,1)

      fruitsList.push(fruit)

  }

}

该if循环中的测试说明了一个重要的.forEach()行为:它跳过空数组的索引(即从未初始化为值的索引)。从 中.slice()删除元素的调用fruits,因此在前两次迭代之后,它甚至不会再尝试执行任何.slice()调用,因为索引 2 和 3 将为空。


这样做的正确方法,如果它是真正的代码,将是


const fruits = ['Apple', 'Banana', 'Mango', 'Pomegranate']

const fruitsList = fruits.map(function(fruit) {

  return [fruit];

});

fruits = []; // if you really want to empty it out

(而且=>函数会更简洁。)


查看完整回答
反对 回复 2021-12-02
?
qq_笑_17

TA贡献1818条经验 获得超7个赞

Splice 修改源数组。

splice() 方法通过删除或替换现有元素和/或在适当位置添加新元素来更改数组的内容。

来源:https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

这意味着当splice()应用于forEach()正在迭代的数组时,它被修改(变短),因此一段时间后它没有元素可以迭代。


查看完整回答
反对 回复 2021-12-02
?
慕慕森

TA贡献1856条经验 获得超17个赞

如果您看到每次迭代后所拥有的是从水果中删除的数组,并且您将该数组推送到新列表中,那么您正在以错误的方式改变原始数组。


使用这种方法,您将保持索引完好无损,在拼接突变期间不会发生变化。


const fruits = ['Apple', 'Banana', 'Mango', 'Pomegranate']

const fruitsList = []


function removeArrayItem(item,index){

    let fruit = fruits.splice(index,1,'')

    fruitsList.push(fruit)

}


fruits.forEach(removeArrayItem)

console.log(fruitsList)

https://codepen.io/psyNiiM/pen/JjjNRaJT


查看完整回答
反对 回复 2021-12-02
  • 3 回答
  • 0 关注
  • 475 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信