
ES2015 Provides a set of unique features to make coding more easier, among these features is the Spread operator and Rest parameters.
Spread operators represented by prefixing a variable with three dots like this “…$variable”. This expression has many uses. First the purpose of this expressions for function calls is to allow the function to except zero or more parameters. For iterables like arrays and object is to allow the expression to be expanded to zero or more elements.
Â
Syntax
// for function calls func(...iterableObj);
// for array literals or string [2, ...iterableObj, 6];
// for objects const objClone = { ...obj };
Â
Examples
Using Spread with arrays literals
The spread operator can be used to do a couple of things when using with arrays:
 – To inject an array into another array
var languages = ['javascript', 'php']; // inject languages array var more_languages = ['.Net', 'Java', ...languages, 'C++', 'ruby']; console.log(more_languages); // output // Array(6) [ ".Net", "Java", "javascript", "php", "C++", "ruby" ]
The above code shows that when adding the first array into the second array using the “…” operator. The operator expands the values of the array resulting that the first array is merged with the second array. This is cool as it saves more time than using the classic ways to merge arrays.
Also you can use the operator multiple times like this:
var more_languages = ['.Net', 'Java',...languages, 'C++', 'ruby', ...languages];
Using the operator at the start or at the end
var more_languages = [...languages, '.Net', 'Java', 'C++', 'ruby'];
var more_languages = ['.Net', 'Java', 'C++', 'ruby', ...languages];
 – To merge two arrays
// first array const even_numbers = [0, 1, 2]; // second array const odd_numbers = [3, 5, 7]; // merged array const merged = [...even_numbers, ...odd_numbers]; console.log(merged); // Array(6) [ 0, 1, 2, 3, 5, 7 ]
As you see merging arrays is so easier than before, and you can go beyond this when merging multiple arrays like this:
var merged = [...['jan', 'feb'], ...['mar', 'apr'], ...['may'], ...['june', 'july'], ...['august']]; console.log(merged); // output Array(8) [ "jan", "feb", "mar", "apr", "may", "june", "july", "august" ]
 – To copy an array
var numbers = [1, 2, 3, 4, 5]; var copied = [...numbers]; console.log(copied); // Array(5) [ 1, 2, 3, 4, 5 ]
The spread operator above copy the array values by creating a new array, this is different when using the assignment operator to copy an array for example if you try to push a new value into the copied array:
copied.push(6); // now copied contain 1, 2, 3, 4, 5, 6 // and numbers contain 1, 2, 3, 4, 5
But if you copy an array using the assignment operator
var copied = numbers; copied.push(6); // now copied and numbers referring to the same array and both contain // 1, 2, 3, 4, 5, 6
Using Spread with objects
To use the spread operator with objects works in the same way as array literals.
let user = {id: 1, name: 'wael salah', ...{email: 'user@domain.com', 'age': 30}}; console.log(user); // output {id: 1, name: "wael salah", email: "user@domain.com", age: 30}
– Merging objects
When merging objects be aware that if there is duplicate keys it will be overwritten and the last one will be used as shown in this code:
let obj1 = {id: 1, name: 'wael salah'}; let obj2 = {name: 'john doe', email: 'user@domain.com'}; let merged = {...obj1, ...obj2}; console.log(merged); // output {id: 1, name: "john doe", email: "user@domain.com"} // name overwritten
– Copying objects
Copying object also can be done with the spread operator, before that people tend to use something like javascript Object.assign().
let clonedObj = {...obj1}; console.log(clonedObj); // output // {id: 1, name: "wael salah"}
The copy of an object creates a brand new object instead of modifying the original object so here if you modified the clonedObj by adding new properties this will not affect obj1 as shown:
clonedObj.email = 'user@domain.com'; console.log(clonedObj); // output // {id: 1, name: "wael salah", email: "user@domain.com"} console.log(obj1) // obj1 still as is // {id: 1, name: "wael salah"}
Using Spread Operator with function calls
Let’s assume we have this function that sum multiple numbers
function sum(a, b, c, d, e) { return a + b + c + d + e; }
Now using the spread operator to call that function
sum(...[1,2,3,4,5])
As you see instead of passing along list of arguments to the function we pass an array whose length is the same as the function parameters count and we preceded it with “…” to expand this array into arguments, this is the same as:
sum(1, 2, 3, 4, 5);
Any argument in the argument list can use spread syntax and it can be used multiple times.
sum(1, ...[2, 3], 4, ...[5]);
Rest Parameters
In the previous example the sum function must accept five numbers to work, but imagine if want to make the sum() function more dynamic and accept a variable number of arguments, this can be achieved by using the Rest Parameters.
The Rest Parameters is the same as spread operators but it mostly used to represent that the function can accept an indefinite number of arguments as an array.
Now if we want to rewrite the sum() function to accept variable number of arguments:
function sum(...args) { return args.reduce((previous, current) => { return previous + current; }); }
To use the function
sum(...[1, 2]); // 3 sum(...[1, 2, -1]); // 2 sum(...[1, 2, 3, 4, 5]); // 15 sum(...[1, 2, 3, 4, 5, 6, 7, 8, 9]); // 45
– If the function declaration has more than one argument only the last argument can be a Rest Parameter like this:
function createPost(title, body, ...otherDetails) { console.log("title", title); console.log("body", body); console.log("otherDetails", otherDetails); } createPost("sample post title", "lorem ipsum", "john doe", "news category");