Question:
I'm taking a look at the new features of EcmaScript6
and saw that the Spread Operator
been implemented.
It looks very similar to PHP's variadic function
(which also uses Spread Operator
).
Here's an example of what the difference between current encodings and Ecmascript6
:
Before:
var max = Math.max.apply(null, [1, 2, 3]);
Later:
var max = Math.max(...[1, 2, 3]);
And also in the declaration of functions:
Before:
function myFunc(name) {
var args = [].slice.call(arguments, 1);
// faça o restante
}
Later:
function myFunc(name, ...args)
{
// faça o restante
}
In PHP, the implementation of variadic function
brought some improvements as improvements:
-
Not having to use
call_user_func_array
-
Not having to use
func_get_args
.
I would like to know that, in javascript, what will be impactful with this implementation of Spread Operadators
?
Answer:
The question itself already brings two of these improvements, right? Well, almost. In fact, the second example is quite different from the first.
The first example shows what is often called a spread operator (*): it comes to the left of a list (an Iterable , usually an array) and spreads or "unfolds" its contents into separate variables. In your example, list items are distributed as arguments at function call time:
var max = Math.max(...[1, 2, 3]); // equivale a Math.max(1, 2, 3)
In ES5, as you've noticed, this is only possible with apply
, which is much less readable.
The second example has the opposite semantics: in a function's parameter list, the ...
does not distribute a list into values, but rather collects the values in a list:
function myFunc(name, ...args) { } // args coleta todos os argumentos passados depois de name
This is often called rest parameters , or remaining parameters. In the role signature, they can only appear at the end. Regardless of the name, it is clearly a syntax improvement, as it eliminates the need for slice.call(arguments, n)
within the function, which would be needed in ES5.
Going back to the spread operator , it has other uses besides what you showed in the first example. In literal arrays, it allows you to concatenate and interpolate arrays:
let umaArray = [3, 4];
let outraArray = [6, 7];
let combo = [1, 2, ...umaArray, 5, ...outraArray];
// combo = [1, 2, 3, 4, 5, 6, 7]
It can also be used on the left side of a destruct operation ( destructuring , very nice feature, a bit like the PHP list
, but more powerful):
[a, ...outros] = [1,2,3,4];
// a = 1
// outros = [2, 3, 4]
Finally, it still allows you to do something that required some juggling in ES5, a kind of apply
combined with new
:
new Date(...[2015,7, 31]);
The ES5 equivalent was this "beauty" here:
new (Date.bind.apply(Date, [null, 2015, 7, 31]));
References
- MDN: Spread operator
- MDN: Rest parameters
- MDN: Destructuring assignment
- ES6 Spread and Butter in Depth
- ECMA-262 – Specification
(*) In the specification this is not even listed as an operator; the language grammar treats the ...
literally, and distinguishes the semantics of spread and rest according to context.