How Spread Operator(…) and REST parameter(…) are Useful!!-JavaScript
We will explore one of the powerful features of the ES6 specification of JavaScript — the Spread Operator.Also will see REST parameter which have similar syntax with different use case.Although the both syntax is simple and similar, but sometimes the implementation is confusing if you do not understand it properly.
So let’s start with first REST Parameter which will be easy to understand and will be more clear with going forward in the article.
What is REST Parameter?
Let’s understand the meaning first.
As name suggest Rest which indicates the — “unused” / “more than expect”and Parameter which indicates the — “input props name of function”.
So it’s a way to handle unused or more than expect function params in Js.
let’s demonstrate the problem with example first to better understanding of REST Parameter:
function getSum(a,b,c){return a+b+c;} // here a,b,c are parameterslet res = getSum(1,2,3,4,5);
//here 10,11 are unused input or more input than expect
So in the above case ,we are trying to get the sum of 1,2,3,4,5 i.e — 15.
But we only get the result of summation of 1,2,3 i.e — 6.
We have the solution for this i.e “arguments” Variable with some downsides which will give you the 100% clarity about what is the REST parameter and it’s actual importance.
arguments variable
arguments is both array-like and iterable inbuilt function variable,but it’s not an array.which has the ability to handle indefinite no of input parameters of a function.
let’s understand with example:
function getSum(){
let sum = 0;
/*
In built arguments array like variable has all input access as:
arguments[0]=1
arguments[1]=2
arguments[2]=3
arguments[3]=4
arguments[4]=5*/for(let arg of arguments){sum += arg;}
return sum
}let res = getSum(1,2,3,4,5);
console.log(res) // 15
This arguments variable has its following downside in those case REST Parameter is useful:
- It’s not an array means that means it doesn’t support array methods so we can’t call like arguments.map(…)
- It’s always contains all parameters so if we want to capture them partially we can’t.
- It’s will not useful in arrow function,since we can’t use this inside arrow to access their own object .let’s understand this point with a proper example.
function outer() {
let innerArrow= () => console.log(arguments[0]);
innerArrow();
}outer(6); // 6// In this case,arrowFunction should print "undefined" but it takes outer function arguments as params ,since to distinguish their local scope with other function,inner function should have "this" access which is not available in arrow function
So to handle such problems REST Parameter comes in the picture.
REST Parameter is is an improved way to handle function parameter, allowing us to more easily handle various input or indefinite number of arguments as parameters in a function.
REST Parameter has simple syntax i.e function parameter with prefix three dots(…).
Lets understand with an example
function getSum(...args){
let sum = 0;
for(let arg of args){sum += arg;}
return sum;
}
console.log(getSum(1,2,3,4,5)) // 15
console.log(getSum(1,2)) // 3NOTE:- you can give any name ...args is not mandatory like above arguments in built variable
In the rest parameter ,We can choose to get the first parameters as variables, and gather only the rest.
function getSum(a,b...,args){
let sum = a+b;
for(let arg of args){sum += arg;}
return sum;
}
console.log(getSum(1,2,3,4,5)) // 15
console.log(getSum(1,2)) // 3
Note: The rest parameters must be at the end.
function getSum(...args,a,b) //errorfunction getSum(a,..args,b) // errorThe ...args must always be last.
Now let’s discuss about the Spread Operator having the same syntax i.e three dots(…).
Spread Operator(…)
We have seen just above that how to get an array from a list of parameter i.e through Rest parameter.
But in some times we need just reverse of it i.e no of separate parameter from an list of array.
let counts = [1,2,3];
console.log(...counts); // 1 2 3
Spread syntax “expands” an array into its elements, while Rest syntax collects multiple elements and “condenses” them into a single element
Spread operator allows an iterable[such as an array,a map, or a set] to expand in places where 0 or more arguments are expected.
Use of Spread Operator:
There are different usages of the spread operator and each usage target to solve a different problem statement.Let’s understand each one through step by step.
NOTE: There are other alternate method to acheive the below use case scenarios as well but using spread operator it’s become quite easy and clean along with some pros.Also we are here to learn about Spread Operator!!
- Expanding Arrays
We can use the spread operator on iterables like a String or an array and it’ll put the contents of the iterable into individual elements.
let fruits= ['Mango', 'Apple'];
console.log(fruits); // Without spread operator console.log(...fruits); // Using spread operatorOutput:
['Mango','Apple']
Mango Apple
Let’s understand above example,fruits is an array variable which contains fruits name.Generally when we print a array its result same as array content which is happening in first case,but in second case we append the spread operator before the array variable which expands the each list items of the array individually.
Sometimes, we may need to convert a string into a list of characters. We can use spread operator for this use-case:
let name= "John";
let chars = [...name];
console.log(chars); // ['J','o','h','n']
NOTE: We can only spread out iterable objects and assign to others variable using ‘[]’,other wise it will throw an error.
let name= "John";
let s1 = ...name; // error
let s2 = [...name] // right// But We can directly use ... to print the
console.log(...name) // ['J','o','h','n']
console.log(s2) // ['J','o','h','n']
2. Function Call Parameter
We can pass the list of items separately of an iterable object to a function.
function getCountSum(a,b,c,d){
return a+b+c+d;
}
let count1 = [1,2,3,4];
let count2 = [1,2];console.log(getCountSum(...count1)) // 10
console.log(getCountSum(...count2,3,4)) // 10
console.log(getCountSum(3,4,...count2)) // 10
console.log(getCountSum(3,...count2,4)) // 10
console.log(getCountSum(...count2,...[3],4)) // 10
Note: We can use …spread variable in any place and any of number times in function call.While In REST Parameter of a function definition parameter we can use that only at end.
3. Constructing Array literal
The spread operator allows you to insert content of one array into the initialized array when you construct an array using the literal form.
let count1 = [1,2];
let count2 = [count1,3,4];
let count3 = [...count1,3,4];console.log(count2); // [[1,2],3,4]
console.log(count3); // [1,2,3,4]
4. Combine/Concatenate Array
Also, we can use the spread operator to concatenate two or more arrays:
let n1= ['a', 'b'];
let n2= ['c', 'd'];
let m1= [n1, n2];
let m2 = [...n1, ...n2];console.log(m1); // [['a', 'b'], ['c', 'd']]
console.log(m2); // ['a','b','c','d']
5. Copying an Array
Also we can copying an array instance by using spread operator:
let a1 = [1,2];
let n1 = a1;
let n2 =[...a1];console.log(n1); //[1,2]
console.log(n2); //[1,2]
You are thinking right now ,What’s the big deal of using spread(…)?Both gives similar result.
While it may looks same but it’s not.Here n1 is entirely equal to a1 instead of copying and assigning the content on other hand using spread we just copy the a1 content reference and assigning to n2. This mean any change in a1 will not affect n2 but it will affect n1.
a1.push(3); // [1,2,3]console.log(a1); //[1,2,3]
console.log(n1); //[1,2,3]
console.log(n2); //[1,2] it will not affect
6. Spread in Object Literal
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.
const o1 = { a: 'a', x: 2 };
const o2 = { b: 'b', y: 3 };
const clonedObj = { ...o1 }; //{ a: "a", x: 2 }
const mergedObj = { ...o1, ...o2 }; // { a: "a", x: 2,b:"b", y: 3 }const appendObj1 = {b:'B',...o1}; // {b:"B",a:"a",x:2}const appendObj2 = {...o2,b:'B'}; // {b:"B",y:3}
In the above ,similarly as array we can clone and merged one and more object into another.
Note: In case of clashing properties, the property of the last object wins.As above we can see that appendObj2 has same property b as o2 obj because of appendObj2 property {b: “B”} comes at last that’s why output is {b: “B”,y:3} NOT {b: “b”,y:3}.
7. Spread with Math Function
JavaScript has a Math object which contains several methods(i.e finding the minimum from a list of numbers, finding maximum etc.) to operate with a set of data, i.e. a list of data.
Consider the case that we want to find the minimum and maximum from a list of numbers,we will write something like this:
console.log(Math.min(0,1,6,-1)); //-1
console.log(Math.max(0,1,6,-1)); // 6
But Now consider that we have an array instead of a list, this above Math object method won’t work and will return NaN.
let arr = [0,1,6,-1];console.log(Math.min(arr)); //NaN
console.log(Math.max(arr)); //NaN
By using of spread operator we can acheive that.
let arr = [0,1,6,-1];console.log(Math.min(...arr)); //-1
console.log(Math.max(...arr)); //6
I hope all the concepts of Rest Parameter and Spread operator has been cleared!!😃
There are still few more related use cases of spread operator other than what i have mentioned above but you can explore by yourself since I’ve already covered almost all use cases with proper detailing.
If you have any doubts feel free to ask in the comment section!!!!