Unexpected behavior of Array.prototype.splice

2019-09-19 03:56发布

问题:

While implementing an internal EventEmitter for a project I was working on, I came across a strange quirk when using Array.prototype.splice inside a for... in loop. The function does not successfully remove the indeces from the array within the loop:

var array = [1, 2, 3, 4, 5], index;

for (index in array) {
    if (index === 2) {
        array.splice(index, 1);
    }

    console.log(array[index]);
}

console.log(array);

Running on Google Chrome version 43, this outputs

1
2
3
4
5
[1, 2, 3, 4, 5]

when I'm expecting something like

1
2
4
5
undefined†
[1, 2, 4, 5]

Is this by design or a bug? I cannot find any documented reference to this behavior.

Possibly, if length is not calculated during each iteration of for... in implementation

回答1:

Great question. :)

In Javascript, Arrays are Objects, which means that Array indices are Object keys. And in Javascript, Object keys are strings.

So your condition index === 2 is always going to be false, because the number 2 is not the same as the string '2'.

One solution would be to continue to use the identity operator (recommended by most) and compare index to the string value '2'

index === '2' 

Or, alternatively, you can use the equality operator which will typecast the comparison (although this will likely get you into trouble at some point)...

index == 2 

but works just fine in your case.