Question

I am reading Functional Javascript, which relies heavily on Underscore for its examples. One example, in particular, is confusing to me. The author uses apply within a function twice: firtst, to concatenate an object and an array into an arguments array, and second to use an Underscore function on that array. The underscore function takes the two parameters that were concatenated, though, so it seems like an unnecessary extra step.

Here is the code in question:

function rename(obj, newNames) {
    return _.reduce(newNames, function(o, nu, old) {
        if (_.has(obj, old)) {
            o[nu] = obj[old];
        }
        return o;
    }, _.omit.apply(null, [].concat.apply(obj, _.keys(newNames))));
};

function rename2(obj, newNames) {
    return _.reduce(newNames, function(o, nu, old) {
        if (_.has(obj, old)) {
            o[nu] = obj[old];
        }
        return o;
    }, _.omit(obj, _.keys(newNames))); // Omitting the apply calls works fine
};

var source = {a: 1, b: 2},
    dictionary = {'a': 'AAA'};

rename(source, dictionary); // Object {a: "AAA"}
rename2(source, dictionary); // Object {a: "AAA"}

What is the reasoning behind using apply in this case?

Was it helpful?

Solution

Check the Underscore docs for omit! You can see that it does not take an array as its second parameter, but rather takes multiple parameters. Valid invocations would be

_.omit({…}, "a")
_.omit({…}, "a", "b")
_.omit({…}, "a", "b", …, "z")

Also have a look at the code of _.omit.

So why does your second invocation work at all? Because the one-element array (['a']) that you're passing in gets stringified and yields the expected property name.

But how can you call omit with variable arguments? Especially, _.keys(newNames) does yield differently sized arrays. And this is just where apply is required.


At least, that's what the author intended to do.

Yet, I stand corrected. If we actually look at the source code, we can see the line

var keys = concat.apply(ArrayProto, slice.call(arguments, 1));

So, by using concat it allows the user to supply a variable amout of strings or arrays of strings. This means you're right, and using apply is just overly complicated.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top