Spread operator
With the new ES2015 standard came a new operator “…” which can split an array into a list and vice versa to group a list into an array. Depending on the function it performs, this parameter has the name “spread” or “rest”. If the operator is in front of the iterable object and “spreads” the iterator (eg array) into individual values creating a list, then it is called “spread”.
Transform a string to a list of arguments
This operator is a replacement for a frequently used problem when it is necessary to cast a string into a list of arguments. And the best example is “expanding” a string in a function’s argument list. This operator is used when calling the function:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function foo (a,b,c){ console.log(a); console.log(b); console.log(c); } argNiz = [1,2,3]; // The problem is that the function does not accept a string: foo(argNiz); // Returns: [1,2,3], undefined, undefined // The old way of solving the problem: foo.apply(null, argNiz); // Returns: 1,2,3 // Novi pristup sa novom sintaksom foo(...argNiz); // Returns: 1,2,3 |
Declarations of an array containing another array
Used within an array declaration that contains another array:
|
1 2 |
var a = [2,3] var b = [1, ...a]; // [1,2,3] |
Cloning an object
With the new standard, it is allowed to use the spread operator within the object literal. This convenience allows us to easily clone objects using the spread operator, without using the Object.assign() method:
|
1 2 3 |
var obj1 = { foo: 'bar', x: 42 }; var clonedObj = { ...obj1 }; // Returns: { foo: 'bar', x: 42 } |
Merging two objects
Using the spread operator makes it easy to join two objects without duplicating properties:
|
1 2 3 4 |
var obj1 = { foo: 'bar', x: 42 }; var obj2 = { foo: 'baz', y: 13 }; var mergedObj = { ...obj1, ...obj2 }; // Returns: { foo: "baz", x: 42, y: 13 } |
Rest operator
Unlimited number of arguments as a string
The Rest syntax allows us to represent an unlimited number of arguments as an array. This operator is used when defining a function by grouping the remaining arguments into an array:
|
1 2 3 4 |
function someFunction(x, y, ...ostatak) { console.log("This is the excess of the arguments passed:" + ostatak); } someFunction(3, 5, 8, 6); // Returns: "This is the excess of arguments passed: 8.6" |
The collected string can be destroyed into individual values if necessary.
|
1 2 3 4 5 6 7 |
function f(...[a, b, c]) { return a + b + c; } f(1, 2, 3) // Returns: 6 f(1) // Returns: NaN (jer su "b" i "c" undefined) f(1, 2, 3, 4) // Returns: 6 (The fourth parameter is not destructed because there is no value to assign) |
List to array transformation
This operator replaces the overcomplicated solution used to cast a list to an array :
|
1 2 3 4 5 6 7 |
function kvadriranje(a, b, c) { // Stari pristup: var niz = Array.prototype.slice.call(arguments); var kvadrat = niz.map(function (clanNiza){ return clanNiza * clanNiza; }); |
New way with rest operator:
|
1 2 3 4 5 6 7 8 9 |
function kvadriranje(a, b, c) { var niz = [...arguments]; // Stari pristup: var niz = Array.prototype.slice.call(arguments); var kvadrat = niz.map(function (clanNiza){ return clanNiza * clanNiza; }); console.log("Kvadrati brojeva su: " + kvadrat) } kvadriranje(1,2,3); // Returns: "Kvadrati brojeva su: 1,4,9" |
BONUS: Spread/rest operator associativity
Each JavaScript operator has its own “importance” which is directly related to associability and how to determine which operation takes precedence in the absence of parentheses. The Sread/Rest operator belongs to the “weaker” operators (ie, the only weaker , “comma” operator). See the operator importance table in the article “JavaScript operator”.
Example
In the JavaScript world, we can come across the following expression:
|
1 2 3 4 |
const result = { name: "results"; ...!!data ? : { default: true } }; |
The essential part of this whole expression is actually this hard-to-understand part:
|
1 |
...!!data ? : { default: true } |

In order to understand the expression, we need to know which operator is more important, i.e. preference when executing an expression. The following list shows the operators in this expression by “meaning”:
- !! (negation operator)
- … ? … : … (ternary operator)
- …(spread operator)
The preceding list determines the flow of the expression: first, with a double negation, the “data” variable is converted to a logical value (read more about this in the article “JS snippets (tips & tricks)”). If we get a TRUE logical value, then the ternary operator enters the scene, which takes the “data” object and then “spreads” it with the spread operator, for the FALSE value, the ternary operator returns the literal object and spreads it with the spread operator.
