Spread Syntax ES6
- In your example given, there is essentially no difference between the two
.concat
is 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
Array
s but alsoMap
andSet
among 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.
Spread syntax ES6 with statement
Spread is not an operator, it's part of the object literal syntax (or at least it will be when the proposal is accepted). You need to write
{...globalStyles.hint, ...(disabled ? globalStyles.hintDisabled : {})},
How does the spread/rest operator in JS work?
There are many resources on this topic other than MDN if you search around.
How does the spread and rest operators in JS work?
JavaScript ES6: Spread Operator and Rest Parameters
Javascript's three dots ( ... ): Spread vs rest operators
Rest parameters and spread syntax
Spread
The spread operator “spreads” the values in an iterable (arrays, strings)
Essentially, spread will iterate over each item of an array in this case. Outputting array[0]
array[1]
array[2]
etc.
var a = [1,2,3];
var b = [4,5,6];
console.log([...a, ...b]); // [1,2,3,4,5,6]
or
var a = ['x', 'y', 'z'];
test(...a);
function test(param1, param2, param3) {
// param1 = 'x'
// param2 = 'y'
// param3 = 'z'
}
Rest
The rest parameter allows us to pass an indefinite number of parameters to a function and access them in an array.
Rest works in a similar way as the spread operator but will iterate over all arguments passed to a function and allow you to access them in array.
test(1,2,3,4,5,6)
function test(...args) {
console.log(args); // [1,2,3,4,5,6]
// Instead of ar
}
JavaScript ES6 - Is this spread syntax or rest syntax?
This is "merging" row
and changed[row.ID]
into a single object. Let's look at what happens when row
is the one with the ID "75864":
// row: {"ID": 75864, "ActType": "DEADLINE", (more properties)}
// changed: {"75864": {"ActType": "OTHER ACTION"}}
// (Note - I changed `changed` so that the ActType specified is different from
// what's already in the row object, otherwise it's really difficult for me to
// demonstrate exactly what's happening here.)
// This is the body of the arrow function:
return changed[row.ID] ? { ...row, ...changed[row.ID] } : row
// Well, changed[row.ID] does exist:
// changed[row.ID]: {"ActType": "OTHER ACTION"}
// So we take this branch of the ternary:
return { ...row, ...changed[row.ID] }
// Basically, this expression works like an array spread, but for objects.
// As a refresher, here's what an array spread might look like:
//
// a = [1, 2, 3]
// b = ['cat', 'dog', 'armadillo']
// c = [...a, ...b]
// c: [1, 2, 3, 'cat', 'dog', 'armadillo']
//
// The array spread works by creating a completely new, empty array. Then
// it adds the items of each array that's spread into it; so first it adds
// all the items of a (1, 2, 3), then all the items of b (cat, dog, armadillo).
// Object spread works pretty much the same way. First we create a completely
// new object: {}.
// Then we add all the properties of row: {ID: 75864, ActType: "DEADLINE",
// "MatterID": 14116, (more properties)}.
// Then it adds the the properties of changed[row.ID]. This is the important
// part, because changed[row.ID] actually *overwrites* any properties that
// we've already added from "row". This makes the result look like this:
return {ID: 75864, ActType: "OTHER ACTION", MatterID: 14116, (more properties)}
// Note that the return value's ActType property is OTHER ACTION, not DEADLINE!
Note that object spread is essentially the same as using Object.assign
with an empty object as the first argument. (Object.assign takes all the properties from the second, third, etc arguments and sets them on the first argument. That means it actually changes - mutates - its first argument; and here, we aren't mutating row
, we're returning a totally new object based on row
(and changed[row.ID]
).) So writing your code with Object.assign would look like this:
return Object.assign({}, row, changed[row.ID])
Spread Syntax vs Rest Parameter in ES2015 / ES6
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'];
Custom class extending Array without using spread syntax
The Array
constructor has two forms: you can pass it all the array elements, or you can pass it the size of the array. You could try using the second form, then copying the array elements in your constructor.
class AnalyserRows extends Array {
constructor(sourceArray) {
super(sourceArray.length);
for (let i = 0; i < sourceArray.length; i++) {
this[i] = sourceArray[i];
}
}
// ...
}
However, this may be very slow for huge arrays. From the quote you gave, it sounds like any of the built-in shortcuts will run into the stack overflow problem.
Related Topics
How to Check If an Element Is Really Visible with JavaScript
Differencebetween State and Props in React
Doesn't JavaScript Support Closures with Local Variables
Turning Off Eslint Rule for a Specific Line
Are Es6 Classes Just Syntactic Sugar for the Prototypal Pattern in JavaScript
How to Split a String into Segments of N Characters
Basic JavaScript Promise Implementation Attempt
What Does [Object Object] Mean? (Javascript)
What Is the Order of Execution in JavaScript Promises
What Is the Cleanest Way to Get the Progress of Jquery Ajax Request
Check If an Element Is Present in an Array
Filtering Array of Objects with Arrays Based on Nested Value
How to Get Evaluated Attributes Inside a Custom Directive
Using Variable Keys to Access Values in JavaScript Objects