Does it make sense to use .apply( ) and pass the s

2020-04-16 05:38发布

问题:

I'm reading Javascript Web Applications, from O'Reilly. At various points in the book, the author uses something along the following:

instance.init.apply(instance, arguments);

Does this make any sense? Isn't this exactly the same as:

instance.init(arguments);

.call() and .apply() are used to manually set the execution context of a function. Why should I use them when I'm intending to use the original execution context anyway?

回答1:

The point is that arguments is an array-like object. Doing ...

instance.init(arguments);

... passes one argument, which is an array-like object containing certain arguments. On the other hand, doing ...

instance.init.apply(instance, arguments);

... will pass the array-like object as separate arguments. It is true that setting instance is kind of useless because you already wrote it, but if using .apply you simply need to set the this value as well.

A quick example of the difference:

function log(a, b, c) {
    console.log(a, b, c);
}

function log2() {
    log.apply(null, arguments); // `this` value is not meaningful here,
                                // it's about `arguments`
}

function log3() {
    log(arguments);
}

log(1, 2, 3);  // logs:  1, 2, 3

log2(1, 2, 3); // logs:  1, 2, 3

log3(1, 2, 3); // logs:  <Arguments>, undefined, undefined
               //        where <Arguments> contains the values 1, 2, 3


回答2:

Using apply() in that example insures that 'this' === instance, instead of DOMWindow if instance.init() is executed from another function/expression.

var x = function(){ debugger; },
    y = function(){ x.apply(x, arguments); },
    z = function() { x(arguments); };

y("abc", true, []); // this === x
z("abc", true, []); // this === DOMWindow

It's simply specifying context.