DEV Community

Cicada0315
Cicada0315

Posted on • Updated on

JS spread operator (...)

Definition

JavaScript ES6 introduced the spread operator and it only worked for arrays. ES2018 expands the spread operator (...) to make it works with own enumerable properties of an object.

Spread syntax (...) allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected.

reference:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

I feel like this definition is hard to understand. So let me put in other words, the spread operator takes an iterable such as array and expands it into elements.

Examples

Array

1. Merge Arrays

Without spread operator, using Array.prototype.concat(),

let array1 = [1, 2, 3];
let array2 = [4, 5, 6];

let newArray=array1.concat(array2);
newArray; //-> [1, 2, 3, 4, 5, 6]
Enter fullscreen mode Exit fullscreen mode

With spread operator,

let array1 = [1, 2, 3];
let array2 = [4, 5, 6];

let mergeArray = [...array1, ...array2];
mergedArray; //-> [1, 2, 3, 4, 5, 6]
Enter fullscreen mode Exit fullscreen mode

2. Clone Array

In JavaScript, arrays are reference types("pass by reference", it just copies address of that array), so you can't just create a new copy of an array using =. When you are change the new array or original array, it will also change the other another like example below:

let original = [1, 2, 3];
let newArray = original;

newArray[0]=5;
newArray; //-> [5, 2, 3]
original; //-> [5, 2, 3]
Enter fullscreen mode Exit fullscreen mode

Oh no, both of them changed. Let's try again with spread operator.

let original = [1, 2, 3];
let newArray = [...original];

newArray[0]=5;
newArray; //-> [5, 2, 3]
original; //-> [1, 2, 3]
Enter fullscreen mode Exit fullscreen mode

Now, original array didn't affect when we changed the newArray, only newArray was modified.

3. String to Array

Using spread operator to a string, it will return an array of individual substrings (split into characters).

let st = 'hello';
let array = [...st];
array; //-> ['h', 'e', 'l', 'l', 'o']
Enter fullscreen mode Exit fullscreen mode

4. Math

The Math object in javascript, the array won't work but with spread operator it will work

let array = [1,2,3,10];
console.log(Math.max(array)); //->NaN
console.log(Math.max(...array)); //->10
Enter fullscreen mode Exit fullscreen mode

reference:
https://www.samanthaming.com/tidbits/92-6-use-cases-of-spread-with-array/
https://www.geeksforgeeks.org/javascript-spread-operator/

Object

The spread operator (…) with objects is used to create copies of existing objects with new or updated values or to make a copy of an object with more properties.

let's say we have 3 objects,

let user1 = {
    name: 'jean',
    age: 30
};
let user2 = {
    name: 'John',
    age: 20
};
let jean = {
    location: 'NY',
    hobby: 'coding'
};
Enter fullscreen mode Exit fullscreen mode

1. Clone Object

Using Object.assign()

let clonedUser = Object.assign({}, user1);
clonedUser; //-> {name: 'jean', age: 30 }
Enter fullscreen mode Exit fullscreen mode

Using Spread Operator

let clonedUser = { ...user1 };
clonedUser; //-> {name: 'jean', age: 30 }
Enter fullscreen mode Exit fullscreen mode

Both of them works same way.

2. Merge Objects (with different properties)

Using Object.assign()

  1. This will modify the user1 too.
let MergedUser = Object.assign(user1, jean);
MergedUser; //-> {name: "jean", age: 30, location: "NY", hobby: "coding"}
user1; //-> {name: "jean", age: 30, location: "NY", hobby: "coding"}
Enter fullscreen mode Exit fullscreen mode
  1. Making new Merged obj, won't modify the user1
let MergedUser = Object.assign({}, user1, jean);
MergedUser; //-> {name: "jean", age: 30, location: "NY", hobby: "coding"}
user1; //-> {name: 'jean', age: 30 }
Enter fullscreen mode Exit fullscreen mode

Without using {} empty object, it will modify the user1. Simply saying that first take the user1 and then add jean to the user1. If you don't want to mutate user1 then you must use empty obj. "let MergedUser = Object.assign({}, user1, jean);" this is saying that create the empty newobj and copy user1 to it and then add jean to that newobj.

Using Spread Operator

let MergedUser = { ...user1, ...jean};
MergedUser; //-> {name: "jean", age: 30, location: "NY", hobby: "coding"}
Enter fullscreen mode Exit fullscreen mode

3. Merge Objects (with same properties)

Using Object.assign

let MergedUser = Object.assign({}, user1, user2);
MergedUser; //-> {name: "John", age: 30}
Enter fullscreen mode Exit fullscreen mode

Using Spread Operator

let MergedUser = { ...user1, ...user2};
MergedUser; //-> {name: "John", age: 30}
Enter fullscreen mode Exit fullscreen mode

The properties are overwritten by other objects that have the same properties later in the parameters order.
This overwriting will come in handy when you pass objects to other functions that update state.

Bonus Update property

const obj = { hi: "x", hello: "y" };
const updatedObj = { ...obj, hi: "z" };
updatedObj; //-> {hi: z, hello: "b"}
Enter fullscreen mode Exit fullscreen mode

This is what I talked earlier when explaining with using Object.assign() with empty obj or not. So in this case, we update obj with new value.

Bonus Create new obj with Updated property of other obj

//using Object.assign()
let user = {id: 1, name: 'jean', age: 30};
let YoungerUser = Object.assign({}, user, {age: user.age - 1})
//using spread operator
let user = {id: 1, name: 'jean', age: 30};
let YoungerUser = {...user, age: user.age - 1}
Enter fullscreen mode Exit fullscreen mode

It's creating new obj, "YoungerUser". Start with a new empty object, copy over everything from the original user, then overwrite the age property with a new value.
reference:
https://www.rockyourcode.com/use-the-spread-operator-to-update-objects/

Top comments (1)

Collapse
 
nikkukn profile image
nikkukn

thanks for the awesome explanation