eri*_*dal 5 javascript arrays node.js
在nodejs REPL上,我试图清理一个定义为的数组,const array = [...] 并且发现使用array.forEach(() => /pop|shift/())不起作用.在这样的表达式之后,数组仍将保留其中的值.
我很清楚更好的清理阵列的方法,比如array.splice(0),但我对这种行为很好奇,似乎反直觉,至少对我而言.
const a = [1, 2, 3]
a.forEach(() => {
a.shift()
})
console.log(a) // [ 3 ]
const b = [1, 2, 3]
b.forEach(() => {
b.pop()
})
console.log(b) // prints [ 1 ]Run Code Online (Sandbox Code Playgroud)
起初我正在使用arr.forEach(() => arr.pop()),所以我虽然其中一个值是短路forEach但是将lambda包裹在一个体块中{ .. }也会产生相同的结果.
结果在不同的节点版本和浏览器中是一致的.所以它似乎是明确定义的行为.
剩余值的数量,仍在结果数组中的值,根据输入数组的长度而变化,似乎是 Math.floor(array.length / 2)
剩余的值总是根据使用的/pop|shift/方法排序,因此一些调用实际上是在改变输入数组.
它也通过调用返回相同的结果 Array.prototype.forEach(array, fn)
从这里查看此引用:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
如果数组现有元素的值发生更改,则传递给回调的值将是 forEach() 访问它们时的值;在访问之前被删除的元素不会被访问。
您从头开始迭代,并在每次迭代中删除最后一个元素。这意味着每次迭代都会向前移动 1,并将长度减少 1。这就是为什么你最终会进行floor(initialLength / 2)迭代。您正在修改您正在修改的同一数组forEach,如上所述,这意味着您将不会为那些pop'd 元素调用回调。