Spread Syntax vs Rest Parameter in ES2015 / ES6
Asked Answered
N

11

83

I am confused about the spread syntax and rest parameter in ES2015. Can anybody explain the difference between them with proper examples?

Nephro answered 24/11, 2015 at 16:9 Comment(9)
One is at the call site, the other is in the parameter list. Or for arrays, one is in the literal, the other is in a destructuring expression.Exuberant
Can anybody explain why it is downvoted?Nephro
Probably because of no shown research effort. Also, where did you find those terms, where/how were they so bad explained that you cannot tell the difference?Exuberant
Thanks @Exuberant but I was in hurry.Nephro
@Exuberant personal opinion, your comments offer more insights than the accepted answer, simply stating expanding vs collapsing doesn't tell their use case, thanks ;)Tenorite
You can refer this blog for rest / spread operator - tejassavaliya.medium.com/…Wilser
I would probably not close this question as a duplicate of What do these three dots in React do?. Why? Because this question explicitly deals with both the rest parameters syntax and the spread syntax, whereas the other question mainly deals with the spread syntax. More important than closing one of these two questions, they are now linked to one another. This makes them both easier to find.Yoon
See an article javascript.info/rest-parameters-spreadRivarivage
@Henke Moreoever, that question deals with spread syntax in JSX tags, not in object literals.Exuberant
C
141

When using spread, you are expanding a single variable into more:

var abc = ['a', 'b', 'c'];
var def = ['d', 'e', 'f'];
var alpha = [ ...abc, ...def ];
console.log(alpha)// alpha == ['a', 'b', 'c', 'd', 'e', 'f'];

When using rest arguments, you are collapsing all remaining arguments of a function into one array:

function sum( first, ...others ) {
    for ( var i = 0; i < others.length; i++ )
        first += others[i];
    return first;
}
console.log(sum(1,2,3,4))// sum(1, 2, 3, 4) == 10;
Curley answered 24/11, 2015 at 16:18 Comment(4)
what about const [a, b, ...c] = [1, 2, 3, 4, 5, 6, 7, 8, 9]?Bundelkhand
@yukulélé this is rest. Read it as a, b and the rest of the array.Zenobia
@Yukulélé its rest and the value of c will be [3,4,5,6,7,8,9]Hecate
You can refer this blog for rest / spread operator - tejassavaliya.medium.com/…Wilser
U
97

ES6 has new feature three dots ...

Here is how we can use these dots:

  1. As Rest/Collector/Gather
var [c, ...m] = [1,2,3,4,5]; // m -> [2,3,4,5]

Here ...m is a collector, it collects the rest of the parameters. Internally when we write:

var [c, ...m] = [1,2,3,4,5]; JavaScript does following

var c = 1,
    m = [2, 3, 4, 5];
  1. As Spread
var params = [ "hello", true, 7 ];
var other = [ 1, 2, ...params ]; // other => [1,2,"hello", true, 7]

Here, ...params spreads so as to adding all of its elements to other

Internally JavaScript does following

var other = [1, 2].concat(params);
Unsuspecting answered 3/3, 2017 at 11:4 Comment(0)
N
18

Summary:

In javascript the ... is overloaded. It performs a different operations based on where the operator is used:

  1. When used in function arguments of a function declaration/expression it will convert the remaining arguments into an array. This variant is called the Rest parameters syntax.
  2. In other cases it will spread out the values of an iterable in places where zero or more arguments (function calls) or elements (array literals) are expected. This variant is called the Spread syntax.

Example:

Rest parameter syntax:

function rest(first, second, ...remainder) {
  console.log(remainder);
}

// 3, 4 ,5 are the remaining parameters and will be 
// merged together in to an array called remainder 
rest(1, 2, 3, 4, 5);

Spread syntax:

// example from MDN:

function sum(x, y, z) {
  return x + y + z;
}

const numbers = [1, 2, 3];

// the numbers array will be spread over the 
// x y z parameters in the sum function
console.log(sum(...numbers));


// the numbers array is spread out in the array literal
// before the elements 4 and 5 are added
const newNumbers = [...numbers, 4, 5];

console.log(newNumbers);
Nitrous answered 23/10, 2018 at 18:7 Comment(1)
The first part of the spread syntax example appears to be taken from JavaScript Demo: Expressions - Spread syntax. Nothing wrong with that as long as you attribute. This is what we want others to do when getting content from us. See Attribution Required and Defending Attribution Required.Yoon
I
7

Javascript's three dots ( ... ) operator can be used in two different ways:

  1. Rest parameter: collects all remaining elements into an array.

var days = ["Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri"];
const [sat, sun, ...weekdays] = days;
console.log(sat); // "Sat"
console.log(sun); // "Sun"
console.log(weekdays); // ["Mon", "Tue", "Wed", "Thu", "Fri"]
  1. Spread operator: allows iterables( arrays / objects / strings ) to be expanded into single arguments/elements.

var weekdays = ["Mon", "Tue", "Wed", "Thu", "Fri"];
var days = [...weekdays, "Sat", "Sun"]; 
console.log(days) // ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]

Note that the spread operator can be the first element, but the rest parameter needs to be the last to collect the rest elements .

Intersex answered 18/7, 2019 at 22:41 Comment(1)
[T]he rest parameter needs to be the last to collect the rest elements. ~ * ~ Confirmed. Good point! Cheers.Yoon
R
6

When we see "..." in the code, it is either rest parameters or the spread operator.

There’s an easy way to distinguish between them:

When ... is at the end of function parameters, it’s “rest parameters” and gathers the rest of the list into the array. When ... occurs in a function call or alike, it’s called a “spread operator” and expands an array into the list. Use patterns:

Rest parameters are used to create functions that accept any number of arguments. The spread operator is used to pass an array to functions that normally require a list of many arguments. Together they help to travel between a list and an array of parameters with ease. For more information about this click here

Recess answered 25/10, 2017 at 10:29 Comment(0)
G
3

Added in ES6 these three dots ... has two meanings, Spread operator and Rest parameter

Spread operator: You use the three dots to expand iterables, by iterables I mean arrays, string, etc. As arguments. For example Math.max() function expect an indeterminate number of arguments so you can use Spread operator to expand elements as arguments on Math.max() function. Here an example from mdn

console.log(Math.max(1, 3, 2));
// expected output: 3

console.log(Math.max(-1, -3, -2));
// expected output: -1

var array1 = [1, 3, 2];

console.log(Math.max(...array1));
// expected output: 3

Another use case is to add, for example having this array

const videoGames = ['mario galaxy', 'zelda wind waker', 'ico'];

You can add it to another array

const favoritesVideoGames = ['Shadow of the colosus', ...videoGames];

Then favoritesVideoGames value is

[ 'Shadow of the colosus', 'mario galaxy', 'zelda wind waker', 'ico' ]

About Rest parameter, here the MDN definition

The rest parameter syntax allows us to represent an indefinite number of arguments as an array.

This means you can pack many elements into a single element

Here an example from MDN

function sum(...theArgs) {
  return theArgs.reduce((previous, current) => {
    return previous + current;
  });
}

console.log(sum(1, 2, 3));
// expected output: 6

console.log(sum(1, 2, 3, 4));
// expected output: 10

I usually get confused with these three points, this illustration by @stephaniecodes helps me to remember its logic. I mention that I took inspiration from this illustration to answer this question.

I hope it is useful.

Gilded answered 25/9, 2018 at 22:57 Comment(0)
N
3

Simple to remember ............

if the triple dots (...) are on the left side its Rest paramenter, if the triple dots are on the right side its Spread parameter.

Remember LRS alphabetically its L then R then S

const [a,b,...c] = [1,2,3,4,5]     // (left) rest

const [d,e] = [1, ...c]             // (right) spread
Neurosurgery answered 5/3, 2021 at 17:36 Comment(0)
L
2

Basically like in Python:

>>> def func(first, *others):
...    return [first, *others]
>>> func('a', 'b', 'c')
['a', 'b', 'c']
Life answered 24/3, 2017 at 19:40 Comment(1)
Python examples to a JavaScript question with no explanation of the difference between rest and spread doesn't answer the OP's question.Tigon
G
0

In reference to this i cant understand how we are passing a function and returning arguments in javascript

Function is a set of instructions that takes some input and processes them and returns result.

here we have an array [1, 2, 3, 4, 5, 6], and filter function iterates over each element and passes each element to positive functions which returns the number if it is even, else skips it.

trace:

1 => Filter(1) => positive(1) => skips 1,
2 => Filter(2) => positive(2) => returns 2,
3 => Filter(3) => positive(3) => skips 3,
...
6 => Filter(6) => positive(6) => returns 6

hence the result [2, 4, 6]

Gales answered 24/9, 2019 at 9:20 Comment(0)
E
0

considering 3 scenarios

1] without using any operator

function add(x, y) {
  return x + y;
}

add(1, 2, 3, 4, 5) // returns 3  (function will takes first 2 arg only)

2] with rest operator

function add(...args) {
  let result = 0;

  for (let arg of args) result += arg;

  return result
}

add(1) // returns 1
add(1,2) // returns 3
add(1, 2, 3, 4, 5) // returns 15

- we can gather any number of arguments into an array

3] with spread operator

const arr = ["Joy", "Wangari", "Warugu"];
const newArr = ["joykare", ...arr];

The value of newArr will be [ 'joykare', 'Joy', 'Wangari', 'Warugu' ]

another one

function add(a, b, c) {
  return a + b + c ;
}
const args = [1, 2, 3];

add(...args);

-We have been using arrays to demonstrate the spread operator, 
but any iterable also works. So, if we had a 
string const str = 'joykare', [...str] translates to [ 'j', 'o', 'y', 'k', 'a', 'r', 'e' ]
Essex answered 3/1, 2020 at 9:48 Comment(0)
D
0

From: Ved Antani, Stoyan Stefanov Book “Object-Oriented JavaScript - Third Edition.” :

Rest parameters

ES6 introduces rest parameters. Rest parameters allow us to send an arbitrary number of parameters to a function in the form of an array. Rest parameter can only be the last one in the list of parameters, and there can only be one rest parameter. Putting a rest operator(...) before the last formal parameter indicates that parameter is a rest parameter. The following example shows adding a rest operator before the last formal parameter:

function sayThings(tone, ...quotes){ 
  console.log(Array.isArray(quotes)); //true 
  console.log(`In ${tone} voice, I say ${quotes}`) 
} 
sayThings("Morgan Freeman","Something serious"," 
 Imploding Universe"," Amen"); 
//In Morgan Freeman voice, I say Something serious,
 Imploding Universe,Amen 

The first parameter passed to the function is received in tone, while the rest of the parameters are received as an array. Variable arguments (var-args) have been part of several other languages and a welcome edition to ES6. Rest parameters can replace the slightly controversial arguments variable. The major difference between rest parameters and the arguments variable is that the rest parameters are real arrays. All array methods are available to rest parameters.

Spread operators

A spread operator looks exactly like a rest operator but performs the exact opposite function. Spread operators are used while providing arguments while calling a function or defining an array. The spread operator takes an array and splits its element into individual variables. The following example illustrates how the spread operator provides a much clearer syntax while calling functions that take an array as an argument:

function sumAll(a,b,c){ 
  return a+b+c 
} 
var numbers = [6,7,8] 
//ES5 way of passing array as an argument of a function 
console.log(sumAll.apply(null,numbers)); //21 
//ES6 Spread operator 
console.log(sumAll(...numbers))//21 
Demerol answered 28/4, 2020 at 8:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.