One would think that in JavaScript:
var array = [1,2,undefined,4];
is the same as:
var array = [1,2];
array.length = 3;
array.push(4);
but it's not. This code shows it:
var array1 = [1,2];
array1.length = 3;
array1.push(4);
var array2 = [1,2,undefined,4];
traverseArray(array1);
traverseArray(array2);
function traverseArray(array) {
console.log("trying: " + array);
console.log("reduce:");
array.reduce(function(prev, current, index, array) {
if(current === undefined) {
console.log("Found undefined");
}
console.log(index+": " +current);
}, undefined);
console.log("for loop:")
for(var i=0;i < array.length;i++) {
var current = array[i];
console.log(i+": " +current);
}
console.log();
}
Output:
trying: 1,2,,4
reduce:
0: 1
1: 2
3: 4
for loop:
0: 1
1: 2
2: undefined
3: 4
trying: 1,2,,4
reduce:
0: 1
1: 2
Found undefined
2: undefined
3: 4
for loop:
0: 1
1: 2
2: undefined
3: 4
Why is undefined in array1 not the same as undefined in array2 and why does the for loop act the same but reduce does not?
array1has three numerically-named properties:0,1, and3.array2has four numerically-named properties:0,1,2, and3. The value of the property named2happens to beundefined.When you ask an object for the value of a property it doesn't have, the result is
undefined.In the
forloop, you ask each array for the values of its properties named0,1,2, and3. Forarray1, the property named2does not exist, so the property access producesundefined. Forarray2, the property does exist, but its value actually isundefined, so you get the same result.On the other hand,
reduceonly operates on properties that actually exist. From the ECMAScript specification, this is howreduceloops over arrays, using a counterk:So, we can see that an index is only used if passes a [[HasProperty]] check.
array1does not have a property named2, so that index is skipped.