Le Moi Le Moi - 1 year ago 90
Javascript Question

Pass function arguments to Object.assign

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

Answer Source

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.