Execute Program

Modern JavaScript: Spread

Welcome to the Spread lesson!

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

  • We've seen ... used to provide variable numbers of arguments to functions:

  • >
    function add(x, y) {
    return x + y;
    }
    const numbers = [1, 2];
    add(...numbers);
    Result:
    3Pass Icon
  • We can also use ... when constructing an array. In this case, ... means "include one array's elements in another array".

  • >
    const numbers = [
    1,
    ...[2, 3],
    4,
    ];
    numbers;
    Result:
  • >
    const middleNumbers = [6, 7];
    const numbers = [5, ...middleNumbers, 8];
    numbers;
    Result:
    [5, 6, 7, 8]Pass Icon
  • When we use ... in this way, it's called the "spread" operator. (We're "spreading" one array's elements across another array.)

  • We can spread multiple arrays in a single expression. The elements will show up in the order they were specified.

  • >
    const numbers1 = [1, 2];
    const numbers2 = [3, 4];
    [...numbers1, ...numbers2];
    Result:
    [1, 2, 3, 4]Pass Icon
  • >
    const numbers1 = [1, 2];
    const numbers2 = [3, 4];
    [...numbers2, ...numbers1];
    Result:
    [3, 4, 1, 2]Pass Icon
  • In the past, we'd merge arrays using their concat method.

  • >
    const nonAdmins = [
    {name: 'Amir'},
    ];
    const admins = [
    {name: 'Betty'},
    ];
    const allUsers = nonAdmins.concat(admins);
    allUsers.map(user => user.name);
    Result:
  • Spreading is generally considered a more readable alternative:

  • >
    const nonAdmins = [
    {name: 'Amir'},
    ];
    const admins = [
    {name: 'Betty'},
    ];
    const allUsers = [...nonAdmins, ...admins];
    allUsers.map(user => user.name);
    Result:
    ['Amir', 'Betty']Pass Icon
  • Spreading also works with objects. There, it means "include all of that object's properties in this object".

  • >
    const amir = {
    name: 'Amir',
    age: 36,
    };
    const amirWithEmail = {
    ...amir,
    email: 'amir@example.com'
    };
    amirWithEmail;
    Result:
  • Order matters when setting object keys. When defining an object literal, the last value assigned to a key wins.

  • >
    const user = {
    name: 'Amir',
    age: 36,
    name: 'Betty',
    };
    user.name;
    Result:
    'Betty'Pass Icon
  • The same rule applies when spreading object keys. The last instance of a key wins, even if it comes from a spread.

  • >
    const user1 = {
    name: 'Amir',
    age: 36
    };
    const user2 = {
    name: 'Betty',
    };
    ({...user1, ...user2});
    Result:
    {name: 'Betty', age: 36}Pass Icon
  • >
    const user1 = {
    name: 'Amir',
    age: 36
    };
    const user2 = {
    name: 'Betty',
    };
    ({...user2, ...user1});
    Result:
    {name: 'Amir', age: 36}Pass Icon
  • This is often used to create a new object from an existing object, but with some properties changed. We spread the original object, then specify the properties that we want to overwrite.

  • >
    const loggedOutUser = {
    name: 'Amir',
    loggedIn: false,
    };
    const loggedInUser = {
    ...loggedOutUser,
    loggedIn: true,
    };
    loggedInUser;
    Result:
    {name: 'Amir', loggedIn: true}Pass Icon
  • Here's a code problem:

    Use spread syntax to write a mergeObjects function that combines two objects.

    function mergeObjects(obj1, obj2) {
    return {...obj1, ...obj2};
    }
    mergeObjects(
    {name: 'Amir', age: 36},
    {name: 'Betty'}
    );
    Goal:
    {name: 'Betty', age: 36}
    Yours:
    {name: 'Betty', age: 36}Pass Icon