Execute Program

Modern JavaScript: Nested Destructuring

Welcome to the Nested Destructuring lesson!

This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!

  • We can destructure nested data, like nested arrays (arrays inside other arrays).

  • >
    const dataPoints = [
    [10, 20],
    [30, 40]
    ];
    const [[x1, y1], [x2, y2]] = dataPoints;
    x1;
    Result:
  • >
    const dataPoints = [
    [10, 20],
    [30, 40]
    ];
    const [[x1]] = dataPoints;
    x1;
    Result:
    10Pass Icon
  • >
    const dataPoints = [
    [10, 20],
    [30, 40]
    ];
    const [[, y1]] = dataPoints;
    y1;
    Result:
    20Pass Icon
  • >
    const dataPoints = [
    [10, 20],
    [30, 40]
    ];
    const [, [x2]] = dataPoints;
    x2;
    Result:
    30Pass Icon
  • Here's a code problem:

    Use destructuring to extract the value 40 from the nested array below. Destructure it into a variable named y2.

    const dataPoints = [
    [10, 20],
    [30, 40]
    ];
    const [, [, y2]] = dataPoints;
    y2;
    Goal:
    40
    Yours:
    40Pass Icon
  • We can also destructure nested objects.

  • >
    const user = {
    name: 'Amir',
    address: {
    city: 'Paris',
    },
    };
    const {address: {city}} = user;
    city;
    Result:
  • In the last example, the address: part only exists so that we can access parts of the address. It doesn't define an address variable. Let's double-check that by re-running the code above, then trying to access the address variable.

  • (The next example causes an error. You can type error when code will result in an error.)

  • >
    const user = {
    name: 'Amir',
    address: {
    city: 'Paris',
    },
    };
    const {address: {city}} = user;
    address;
    Result:
    ReferenceError: address is not definedPass Icon
  • If we want to get the entire address object and also get the city, we can ask for that explicitly, as in the next example. Pay close attention to the destructuring syntax here!

  • >
    const user = {
    name: 'Amir',
    address: {
    city: 'Paris',
    },
    };
    const {address, address: {city}} = user;
    [city, address];
    Result:
    ['Paris', {city: 'Paris'}]Pass Icon
  • Here's a code problem:

    Use destructuring to extract Betty's cat's name, which is stored in a nested object. Store it in the name variable. (That variable name matches the name key in cat, which makes the destructuring easier than it would be if it didn't match.)

    const user = {
    name: 'Betty',
    cat: {
    name: 'Keanu',
    age: 2,
    },
    };
    const {cat: {name}} = user;
    name;
    Goal:
    'Keanu'
    Yours:
    'Keanu'Pass Icon
  • Destructuring also works on arrays and objects nested inside each other. (Be careful of the , below. It skips the first array element, so we're only extracting the second one.)

  • >
    const users = [{name: 'Amir'}, {name: 'Betty'}];
    const [, {name}] = users;
    name;
    Result:
    'Betty'Pass Icon
  • What about when we want to destructure multiple different variables at the same time? We could write one const (or let) per object.

  • >
    const user = {name: 'Amir'};
    const address = {city: 'Paris'};
    const { name } = user;
    const { city } = address;
    [name, city];
    Result:
    ['Amir', 'Paris']Pass Icon
  • However, we can also do all of that in one line. We can destructure multiple values by wrapping them in an array, then immediately destructuring it.

  • >
    const user = {name: 'Amir'};
    const address = {city: 'Paris'};
    const [{name}, {city}] = [user, address];
    [name, city];
    Result:
    ['Amir', 'Paris']Pass Icon
  • (Whether you prefer that style is a matter of personal taste, but it's good to know that it's possible!)

  • Finally, let's recap why destructuring is useful. The most obvious benefit is that it makes code shorter. But merely shortening code isn't inherently good. Many methods for shortening code also make it less readable. In the case of destructuring, there's another, more subtle benefit: predictability.

  • Some of JavaScript's array and object methods change the array or object, but others don't. For example, the array methods filter and slice don't change the array that they're called on, but the sort and reverse methods do change the array. To use these methods effectively, we have to memorize which methods work in which ways. (We have a separate JavaScript Arrays course that can help with that!)

  • Destructuring doesn't modify the objects or arrays we destructure, so we never have to worry about this. When someone else reads our destructuring code later, that's one less thing that they have to think about.

  • (There is technically one exception: if we're destructuring a getter property with side effects that change some object, then destructuring will trigger those side effects. But getters should never have externally-visible side effects in the first place, so hopefully you'll never encounter that!)