Michael Sutherland
Michael Sutherland

Reputation: 547

What is happening under the hood in javascript when using the Array brackets notation

I have generally found javascript to be transparent, in that there are very few black boxes where "magic" just happens and you should just accept and look the other way, however I have not found any answer to how the Array brackets [] notation actually works under the hood.

let arr = [4, 5, 6, 7]
console.log(arr[3]) // <- How does this work?

What is javascript doing to access the item at index 3. Does it internally call some method on the Array.prototype?

With an object, the [] is a shortcut for a property accessor.

let obj = {
  a: 'hello',
  b: 'world'
}
obj['a'] === obj.a // true

Is an array then just an object with a long list of integer based properties?

let objArray = {
   0: 'hello',
   1: 'world'
}
let realArray = ['hello', 'world']

objArray[0] === 'hello' // true
realArray[0] === 'hello' // true

objArray.0 // SyntaxError: Unexpected number
realArray.0 // SyntaxError: Unexpected number

I have seen many many online discussions that all come to the conclusion that you cannot overload the brackets notation to truly subclass an Array but I have never seen an explanation on what magic is happening under the hood that allows the Array to work the way it does.

The obvious follow up question is whether there is any way to intercept the bracket notation access to define your own behavior, but I think I already know the answer to that.

Upvotes: 4

Views: 1928

Answers (2)

Scott Sauyet
Scott Sauyet

Reputation: 50787

You'd probably have to look at the implementation code to know precisely what's going on, but the basic idea is that arrays are actually layered atop objects.

This is backwards:

With an object, the [] is a shortcut for a property accessor.

The bracket notation is more fundamental. Thus, obj['foo'] and obj.foo work the same, but there is no equivalent for obj['foo & bar'], which is perfectly legitimate, and will respond with a value if obj has a key named "foo & bar".

Is an array then just an object with a long list of integer based properties?

Not quite, but you're not far off. Arrays are objects with the Array prototype, and with a little bit of additional magic to set the length property when new keys are added, or remove keys when that length is set.

And no, you cannot override the [] operator for your own purposes.

Upvotes: 2

LocalPCGuy
LocalPCGuy

Reputation: 6116

Is an array then just an object with a long list of integer based properties?

Yes, in it's simplest form, an Array is an Object with a list of integer base properties that is based on the Array prototype (which gives access to all the array methods like map, forEach, etc.)

As for intercepting the bracket notation, no, I have not seen anything that would allow that besides creating your own Object that has the methods you need (and then only access that object via the appropriate methods).

More info from MDN:

Arrays are list-like objects whose prototype has methods to perform traversal and mutation operations. Neither the length of a JavaScript array nor the types of its elements are fixed. Since an array's length can change at any time, and data can be stored at non-contiguous locations in the array, JavaScript arrays are not guaranteed to be dense; this depends on how the programmer chooses to use them. In general, these are convenient characteristics; but if these features are not desirable for your particular use, you might consider using typed arrays.

Arrays cannot use strings as element indexes (as in an associative array) but must use integers. Setting or accessing via non-integers using bracket notation (or dot notation) will not set or retrieve an element from the array list itself, but will set or access a variable associated with that array's object property collection. The array's object properties and list of array elements are separate, and the array's traversal and mutation operations cannot be applied to these named properties.

Upvotes: 1

Related Questions