1

So I was debugging one day when I came across this case in JavaScript.

var arrayA = [1, , 1],
    arrayB = [1, void 0, 1];

Now at first glance arrayA and arrayB look similar but when I tried this code in the Google Chrome Developer Console, things got weird:

Defining Array A and Array B

As you can see here, arrayB (the second one) has all it's members listed, including the undefined element.

But it's not the same with arrayA, ignoring the second member (arrayA[1]) even though it's undefined.

There's a problem here when it comes to how arrayA and arrayB are indexed, even though they are practically the same.

Indexing Array A

Everything is fine and dandy when iterating through arrayA using for and for...of statements but when using the for...in statement, the array's second element (arrayA[1]) is skipped over.

Indexing Array B

However, every element of arrayB was recognized when using all for loop variations.

This has also been tested on Mozilla Firefox and Microsoft Edge as well with the same results.

Is there any explanation for why this is so? Why is arrayA treated differently (no matter how slightly) from arrayB — using for...in statements?

I apologize if the images aren't ideal, they were just to show I was using the Google Chrome Developer Console.

And my thanks in advance for anyone willing to answer the question.

EDIT

Just to add, the custom depth property in the arrays do not have any effect on the arrays, even without them I still get the same result.

6
  • 2
    console.log(Array(100)) Commented Jun 25, 2018 at 21:26
  • 2
    Arrays with empty slots are different to arrays that have slots filled with undefined. See e.g. stackoverflow.com/a/44471705/3001761. Methods like forEach are explicitly documented as not including uninitialised elements. Commented Jun 25, 2018 at 21:28
  • It seems you are on to something, @epascarello. I just tried the code and it has the same behavior as the arrays in the question. Any idea why? Commented Jun 25, 2018 at 21:29
  • Because Array(size) also creates an array containing size empty slots. Commented Jun 25, 2018 at 21:31
  • sounds like you can use array.hasOwnProperty(n) to split the hairs you need. Commented Jun 25, 2018 at 21:32

2 Answers 2

3

Your arrayB is what arrays usually look like, they are filled with values.

However, your method ( as well as using Array(n)) can create sparse arrays, array in which some of the values are missing. Arrays, after all, are only special objects meaning that they are key values collection so your first array looks like

{"0": 1, "2": 1 }

while your second looks like

{"0": 1, "1": undefined, "2": 1}

The way to see it is to consider sparse arrays a quirk of the language and avoid it because they don't really have a use case. If you want an array, don't make it sparse, otherwise, use an object ( or an ES6 Map / Set, according to your use case)

Sign up to request clarification or add additional context in comments.

Comments

3

empty is used to distinguish that there is actually no key at that position (for...in enumerates the keys):

var arrayA = [1, , 1], arrayB = [1, void 0, 1];
    
console.log( { ...arrayA } );   // { "0": 1, "2": 1 }
console.log( { ...arrayB } );   // { "0": 1, "1": undefined, "2": 1 }

console.log( 1 in arrayA );   // false
console.log( 1 in arrayB );   // true

console.log( JSON.stringify(arrayA) );   // "[1,null,1]"
console.log( JSON.stringify(arrayB) );   // "[1,null,1]"


As a side note, JavaScript Array is just an object where the positive integer keys are used :

var a = []
a[1] = 1
a.b = 'c'
a[-1] = -1
a[.1] = .1
    
console.log( a );   // [undefined, 1] but DevTools shows "►(2) [empty, 1, b: "c", -1: -1, 0.1: 0.1]
console.log( { ...a } );   // { "1": 1, "b": "c", "-1": -1, "0.1": 0.1 }
console.log( JSON.stringify(a) );   // "[null,1]"

(but that is not the case for TypedArrays)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.