- In your example given, there is essentially no difference between the two
.concatis significantly more efficient: http://jsperf.com/spread-into-array-vs-concat because...(spread) is merely syntax sugar on top of more fundamental underlying syntax that explicitly iterates over indexes to expand the array.- Spread allows sugared syntax on top of more clunky direct array manipulation
To expand on #3 above, your use of spread is a somewhat contrived example (albeit one that will likely appear in the wild frequently). Spread is useful when - for example - the entirety of an arguments list should be passed to .call in the function body.
function myFunc(){
otherFunc.call( myObj, ...args );
}
versus
function myFunc(){
otherFunc.call( myObj, args[0], args[1], args[2], args[3], args[4] );
}
This is another arbitrary example, but it's a little clearer why the spread operator will be nice to use in some otherwise verbose and clunky situations.
As @loganfsmyth points out:
Spread also works on arbitrary iterable objects which means it not only works on
Arrays but alsoMapandSetamong others.
This is a great point, and adds to the idea that - while not impossible to achieve in ES5 - the functionality introduced in the spread operator is one of the more useful items in the new syntax.
For the actual underlying syntax for the spread operator in this particular context (since ... can also be a "rest" parameter), see the specification. "more fundamental underlying syntax that explicitly iterates over indexes to expand the array" as I wrote above is enough to get the point across, but the actual definition uses GetValue and GetIterator for the variable that follows.
Taking the questions out of order, let's start with the fundamental question: What exactly is the use of spread syntax?
Spread syntax basically unpacks the elements of an iterable such as an array or object. Or, for the more detailed explanation from the MDN Web Docs on spread syntax:
Spread syntax allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected.
Following are some simple examples of typical use cases for spread syntax and an example of the difference between spread syntax and rest parameters (they may look the same, but they perform nearly opposite functions).
Function call:
const multiArgs = (one, two) => {
console.log(one, two);
};
const args = [1, 2];
multiArgs(...args);
// 1 2
Run code snippetEdit code snippet Hide Results Copy to answer Expand
Array or string literal:
const arr1 = [2, 3];
const arr2 = [1, ...arr1, 4];
console.log(arr2);
// [1, 2, 3, 4]
const s = 'split';
console.log(...s);
// s p l i t
Run code snippetEdit code snippet Hide Results Copy to answer Expand
Object literal:
const obj1 = { 1: 'one' };
const obj2 = { 2: 'two' };
const obj3 = { ...obj1, ...obj2 };
console.log(obj3);
// { 1: 'one', 2: 'two' }
Run code snippetEdit code snippet Hide Results Copy to answer Expand
Rest parameter syntax is not the same as spread syntax:
Rest parameter syntax looks the same as spread syntax but actually represents an unknown number of function arguments as an array. So rather than "unpacking" the iterable, rest parameters actually package multiple arguments into an array.
const multiArgs = (...args) => {
console.log(args);
};
multiArgs('a', 'b', 'c');
// ['a', 'b', 'c']
Run code snippetEdit code snippet Hide Results Copy to answer Expand
Spread syntax performance / efficiency:
To address the question about efficiency compared to other methods, the only honest answer is that "it depends". Browsers change all the time and the context and data associated with a particular function create wildly different performance outcomes, so you can find all sorts of conflicting performance timings that suggest spread syntax is both amazingly faster and ridiculously slower than various array or object methods you might use to accomplish similar objectives. In the end, any situation where optimizations for speed are critical should be comparison tested rather than relying on generic timings of simplistic functions that ignore the specifics of your code and data.
Comparison to concat():
And finally a quick comment regarding the difference between spread syntax and concat() shown in the question code. The difference is that spread syntax can be used for a lot more than just concatenating arrays, but concat() works in older browsers like IE. In a situation where you are not concerned about compatibility with older browsers and micro optimizations for speed are unnecessary, then the choice between spread syntax and concat() is just a matter of what you find more readable: arr3 = arr1.concat(arr2) or arr3 = [...arr1, ...arr2].