While on the nodejs REPL I was trying to clean up an array defined as const array = [...]
and just found out that using array.forEach(() => /pop|shift/())
would not work. After such expression the array will still hold values in it.
I'm well aware of better methods to clean the array, like array.splice(0)
, but I'm really curious about this behavior as seems counter-intuitive, at least for me.
Here's the test:
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 ]
Notes
At first I was using
arr.forEach(() => arr.pop())
, so I though that one of the values was short-circuiting theforEach
but wrapping the lambda in a body-block{ .. }
will also produce the same results.The results are consistent across different node versions and browsers .. so it seems like it's well-defined behavior.
The quantity of leftover values, those still in the result array, change depending on the length of the input array, and seems to be
Math.floor(array.length / 2)
The leftover values are always ordered accordingly to the
/pop|shift/
method used, so some of the calls are actually changing the input array.It also returns the same results by calling
Array.prototype.forEach(array, fn)