Execute Program

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 someObject is 'object'.

  • >
    typeof {name: 'Amir'};
    Result:
  • But typeof someArray is also 'object'!

  • >
    typeof [];
    Result:
    'object'Pass Icon
  • >
    typeof ['a', 'b', 'c'];
    Result:
    'object'Pass Icon
  • 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:
    5Pass Icon
  • >
    const arr = ['a', 'b', 'c'];
    arr.six = 6;
    arr['six'];
    Result:
    6Pass Icon
  • 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:
    3Pass Icon
  • 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 teamMembers array. We could store a limit number directly on the array.

  • >
    const teamMembers = [
    'ebony@example.com',
    'fang@example.com',
    ];
    teamMembers.limit = 3;
    teamMembers.length <= teamMembers.limit;
    Result:
    truePass Icon
  • 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 limit property.

  • 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:
    falsePass Icon
  • 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 .forEach will ignore extra array properties.

  • >
    const arr1 = ['a', 'b'];
    const arr2 = [];
    arr1.five = 5;
    arr1.forEach(i => arr2.push(i));
    arr2;
    Result:
    ['a', 'b']Pass Icon
  • Second, extra properties will show up if we treat the array like an object. For example, we can use Object.keys to 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: