Reputation: 1025
Say I have a function to compose an object from other objects, and I am passing arguments to the function - initially an object literal, and then the objects I want to compose to extent the object:
composeFunc({}, obj1, obj2, obj3);
The number of args passed is optional, how do I then pass the args to Object.assign()
starting at the 2nd arg. So the function would resemble the following:
function composeObj(objs) {
return Object.assign(arguments[1], arguments[2], arguments[3]... etc);
}
Thanks in advance :)
Upvotes: 7
Views: 3166
Reputation: 3593
ES2015:
function composeObj(objs, ...rest){
return Object.assign(...rest);
}
rest
will be a true array of all of the arguments starting from the second one.
And the Babel-output:
function composeObj(objs) {
for (var _len = arguments.length, rest = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
rest[_key - 1] = arguments[_key];
}
return Object.assign.apply(Object, rest);
}
This seems to be a utility-function that might be used all over the place. As soon as you pass arguments
to an other function like Array.prototype.slice()
or Array.from()
, composeObj
won't be optimized by the JS-compiler anymore. So, don't do that.
Everything else has already been said on T.J. Crowders Answer and the comments; just showing the better implementation.
Upvotes: 4
Reputation: 1074286
If you're using ES2015 rather than just a shim, you can use spread notation, Array.from
, and slice
:
function composeObj(objs) {
return Object.assign(...Array.from(arguments).slice(1));
}
Or just using slice
directly rather than after Array.from
:
function composeObj(objs) {
return Object.assign(...Array.prototype.slice.call(arguments, 1));
}
...see Thomas' answer using rest args, as that's the right way to do this in ES2015.
If you're not using ES2015, you can do the same thing with just a shimmed Object.assign
via apply
:
function composeObj(objs) {
return Object.assign.apply(Object, Array.prototype.slice.call(arguments, 1));
}
There, we're using Function#apply
instead of the spread operator (since ES5 and earlier don't have the spread operator). Function#apply
calls the function you call it on using the first argument as this
during the call, and using the array (or array-like thing) you give it as a second argument as the arguments for the call.
So say you have:
obj.foo(1, 2, 3);
The equivalent using Function#apply
is:
obj.foo.apply(obj, [1, 2, 3]);
The first argument, obj
, tells apply
what to use as this
during the call. The second argument is an array of arguments to use.
But if you use the spread operator, there's no need, it spreads out its array-like operand into discrete arguments.
Upvotes: 7