JavaScript Arrays: Arrays Are Objects
Welcome to the Arrays Are Objects lesson!
JavaScript arrays are a special type of JavaScript object. This is unusual and has some surprising implications.
This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!
Most programming languages have an array data type that's separate from other data types. JavaScript is unusual here: in JavaScript, arrays are a special type of object.
We can see this by using
typeof. When we have a regular object,typeof someObjectis'object'.>
typeof {name: 'Amir'};Result:
But
typeof someArrayis also'object'!>
typeof [];Result:
'object'
>
typeof ['a', 'b', 'c'];Result:
'object'
This doesn't impact most common array operations. However, there are some surprising effects, and they can cause problems in real-world systems. Most notably, we can assign arbitrary properties to an array.
>
const arr = ['a', 'b', 'c'];arr['five'] = 5;arr.five;Result:
5
>
const arr = ['a', 'b', 'c'];arr.six = 6;arr['six'];Result:
6
These new properties don't change the array elements. As a result, they don't affect its
length.>
const arr = [1, 2];arr['name'] = 'some numbers';arr;Result:
>
const arr = ['a', 'b', 'c'];arr['five'] = 5;arr.length;Result:
3
In most cases, extra array properties are created by mistake. When other programmers read the code and see an array, they won't expect it to have these extra properties.
Here's an example. Imagine that we're building a service where one account can have multiple team members. The more team members a customer has, the more money we charge them. We need to keep track of both the members and the limit (how many team members are allowed in this account).
Somewhere in our application, we have a
teamMembersarray. We could store alimitnumber directly on the array.>
const teamMembers = ['ebony@example.com','fang@example.com',];teamMembers.limit = 3;teamMembers.length <= teamMembers.limit;Result:
true
This works, but it's not a good idea because it's surprising. Most arrays don't have metadata stored on object properties. When an array does have extra properties, other programmers won't expect it, which can lead them to make mistakes. For example, they might build a new array and pass it to a function, not realizing that the function expects the array to have this unusual
limitproperty.It's better to use an object in this case.
>
const team = {members: ['ebony@example.com','fang@example.com','gabriel@example.com',],memberLimit: 2,};team.members.length <= team.memberLimit;Result:
false
Now we have two nicely separate concepts: there's a list of team members, and there's a numerical limit on the number of members. Together, the members and the member limit form a team object. If a function needs the full team, we can pass that object; but if it only needs the members, we can pass only the array. Nothing about this is surprising or unusual.
A couple more details about extra properties on arrays. First, looping with
.forEachwill ignore extra array properties.>
const arr1 = ['a', 'b'];const arr2 = [];arr1.five = 5;arr1.forEach(i => arr2.push(i));arr2;Result:
['a', 'b']
Second, extra properties will show up if we treat the array like an object. For example, we can use
Object.keysto list the properties in an object. We'll get all of the array indexes (not the values), plus any extra properties that we added.>
const person = {name: 'Amir', likesOlives: true};Object.keys(person);Result:
>
const arr1 = ['a', 'b'];arr1.five = 5;Object.keys(arr1);Result: