JavaScript Object Spread

Summary: in this tutorial, you will learn how to use the JavaScript object spread (...) in ES2018 to clone an object or merge objects into one.

Introduction to the JavaScript object spread Operator

In ES6, you use the spread operator (...) to unpack elements of an array. The spread operator can be very useful to clone an array. For example:

let colors = ['red', 'green', 'blue'];
let rgb = [...colors];
console.log(rgb);
Code language: JavaScript (javascript)

Output:

[ 'red', 'green', 'blue' ]    
Code language: JSON / JSON with Comments (json)

In this example, the spread operator (...) unpacks elements of the colors array and places them in a new array rgb. The spread operator (...) can be used to merge two or more arrays into one as shown in the following example:

let rgb = [ 'red', 'green', 'blue' ];
let cmyk = ['cyan', 'magenta', 'yellow', 'black'];
let merge = [...rgb, ...cmyk];
console.log(merge);
Code language: JavaScript (javascript)

Output:

[ 'red', 'green', 'blue', 'cyan', 'magenta', 'yellow', 'black' ]
Code language: JSON / JSON with Comments (json)

ES2018 expands the spread operator (...) to make it work with its own enumerable properties of an object. Suppose that you have a circle object with one property radius:

const circle = {
    radius: 10
};
Code language: JavaScript (javascript)

The following example uses the spread operator (...) to create an coloredCircle object that has all the properties of the circle object and an additional property color:

const coloredCircle = {
    ...circle,
    color: 'black'
};

console.log(coloredCircle);
Code language: JavaScript (javascript)

Output:

{
    radius: 10,
    color: 'black'
}
Code language: CSS (css)

JavaScript Object spread operator use cases

1) clone an object

You can use the spread operator to clone the own enumerable properties of an object:

const circle = {
    radius: 10
};

const clonedCircle = {...circle};

console.log(clonedCircle);
Code language: JavaScript (javascript)

Output:

{ radius: 10 }
Code language: CSS (css)

Note that cloning is always shallow. For example:

const circle = {
    radius: 10,
    style: {
        color: 'blue'
    }
};

const clonedCircle = {
    ...circle
};


clonedCircle.style = 'red';

console.log(clonedCircle);
Code language: JavaScript (javascript)

Output:

{ radius: 10, style: 'red' }
Code language: CSS (css)

2) Merging objects

Like arrays, you can use the spread operator (...) to merge two objects:

const circle = {
    radius: 10
};

const style = {
    backgroundColor: 'red'
};

const solidCircle = {
    ...circle,
    ...style
};

console.log(solidCircle);
Code language: JavaScript (javascript)

Output:

{ radius: 10, backgroundColor: 'red' }
Code language: CSS (css)

Spread operator vs. Object.assign()

The spread operator (...) defines new properties in the target object while the Object.assign() method assigns them. It has two side effects.

1) Target objects with setters

The Object.assign() invokes setters on the target object while the spread operator doesn’t. The following illustrates how to clone an object using both Object.assign() and spread operator (...). However, only the Object.assign() method triggers the setters:

class Circle {
    constructor(radius) {
        this.radius = radius;
    }
    set diameter(value) {
        this.radius = value / 2;
        console.log('SET ', value);
    }
    get diameter() {
        return this.radius * 2;
    }
}

let circle = new Circle(100);

let cloneCircle1 = Object.assign(circle, {
    diameter: 200
});

let cloneCircle2 = {
    ...circle
};
Code language: JavaScript (javascript)

Output:

SET  200

2) Target objects with read-only properties

If a target object has a read-only property, you cannot use Object.assign() method to assign a new value to that property. However, the spread operator ( ...) can define a new property. Suppose you have an object called blueSquare whose the color property is readonly:

const blueSquare = {
    length: 100,
    color: 'blue'
};

Object.defineProperty(blueSquare, 'color', {
    value: 'blue',
    enumerable: true,
    writable: false

});

console.log(blueSquare);
Code language: JavaScript (javascript)

Output:

{ length: 100, color: 'blue' }Code language: CSS (css)

The following uses the spread operator (...) to merge the style and blueSquare objects:

// merge style and blueSquare objects:
const style = {
    color: 'green'
};

const greenSquare = {
    ...blueSquare,
    ...style
};

console.log(greenSquare);
Code language: JavaScript (javascript)

Output:

{ length: 100, color: 'green' }Code language: CSS (css)

However, if you use the Object.assign() method, you will get an error:

// merge style and redSquare objects: ERROR
const redSquare = Object.assign(blueSquare, {
    color: 'red'
});Code language: JavaScript (javascript)

Error:

TypeError: Cannot assign to read only property 'color' of object '#<Object>'Code language: JavaScript (javascript)

Summary

  • Object spread operator (...) unpacks the own enumerable properties of an object.
  • Use the object spread operator to clone an object or merge objects into one. Cloning is always shallow.
  • When merging objects, the spread operator defines new properties while the Object.assign() assigns them.
Was this tutorial helpful ?