Spread Syntax VS Rest Parameter in Es2015/Es6

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'];

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])

Use default parameter when using the spread syntax in ES6?

No, a rest parameter gets assigned an empty array when there are no arguments left; there is no way to provide a default for it.

You'll want to use

function logEach(...things) {
for (const thing of (things.length ? things : ['nothing to Log'])) {
console.log(thing);
}
}

ES6 destructure and spread together as arguments into a React Component

Something like this. Where everythingElseExceptTitleAndDescription creates a new object with all enumerable own properties of the argument except title and description

const index = (arg) => {
let title = arg.title;
let description = arg.description;
let props = everythingElseExceptTitleAndDescription(arg);
return (
<div>

</div>
)
}

React rest parameters syntax vs spread syntax

{ ...rest } is effectively doing a shallow copy of the original rest object. It keeps the original shape, but it's a different reference point in memory.

rest also obviously keeps the same shape, because it's the same object. You're simply passing the reference.

{ rest } doesn't work because it creates a new object and assigns the old rest object as a value to the key "rest".


As an example to the above 3 scenarios, say your original props shape is as follows:

{
children: <div>,
label: 'Foo',
value: 5
};

After creating an object and passing it through the constructor ({ children, ...rest }), children has been separated from rest, leaving you with the following object:

{
label: 'Foo',
value: 5
};

With { ...rest }, the object remains the same shape:

{
label: 'Foo',
value: 5
};

With rest, the object remains not only the same shape, but literally the same object:

{
label: 'Foo',
value: 5
};

With { rest }, you're assigning the old rest to the "rest" key:

{
rest: {
label: 'Foo',
value: 5
},
};

Since the component expects the first shape, and doesn't expect properties under a rest key, this last case fails as you've observed.

Question about the syntax of using the spread operator to 'spreads' object(s) as an argument

Let us consider the function definition: const merge = ( ...objects ) => ( { ...objects } );. Here the parameter ...objects is using the spread operator to create an array of all the arguments passed to this function. That makes it possible to pass any arbitrary number of parameters and it will create a corresponding array. If you look at what is produced it may look like this:

[ { foo: 'bar', x: 42 }, { foo: 'baz', y: 13 } ]

Within the body of the function you are now spreading the array itself. Wrapping that in the {} creates the object. But, since you are using the implicit return (without the return statement) there might be some ambiguity between the {} for the object and the {} that normally wraps the body of the function. Hence the () wrapping the whole statement.

That function could have been written like this:

const merge = (...objects) => {
return { ...objects };
}

Quick question about ES6 spread operator on objects

Objects cannot have duplicate keys. If you assign a key to an object when that object already has said key, or write an object initializer with duplicate keys, the prior value at that key will be overwritten:

const obj = {  foo: 'foo',  bar: 'bar',};
obj.foo = 'new';console.log(obj);

ES6 Spread operator (Rest Parameter) - syntax fails with Safari 9

Use arguments object

// call your timerTest function
timerTest(hasClass, 1000000, e, "x");

function timerTest(func, iterations) {

if (typeof iterations == "undefined"){
iterations = 1;
}
var start = performance.now();
//Get parameters from arguments
var args = Array.prototype.slice.call(arguments, 2);

for (var i = 0; i < iterations; i++){
func.apply(this, args);
}

var funcName = /function ([^\(]+)/.exec(func.toString())[0];
v("Time to run " + funcName + " for " + iterations + " time(s): " + (performance.now() - start));
return performance.now() - start;
}


Related Topics



Leave a reply



Submit