Nick Zalutskiy
Nick Zalutskiy

Reputation: 15430

Preserving the function's scope when using function.apply(...)

Consider the following example:

var funcToCall = function() {...}.bind(importantScope);

// some time later
var argsToUse = [...];
funcToCall.apply(someScope, argsToUse);

I want to preserve 'importantScope' of funcToCall. Yet, I need to use apply to apply an unknown number of arguments. 'apply' requires that I provide 'someScope'. I don't want to change the scope, I just want to apply the arguments to the function and preserve its scope. How would I do that?

Upvotes: 3

Views: 2001

Answers (1)

Tim Down
Tim Down

Reputation: 324567

You can pass any old object (including null) as the first argument to the apply() call and this will still be importantScope.

function f() {
    alert(this.foo);
}

var g = f.bind( { foo: "bar"} );

g(); // Alerts "bar"
g.apply(null, []); // Alerts "bar"

The bind method creates a new function in which the this value is guaranteed to be the object you passed in as the parameter to the bind call. Regardless of how this new function is called, this will always be the same. A simple implementation would look like this (note the implementation specified ECMAScript 5 and that in Prototype does more than this but this should give you the idea):

Function.prototype.bind = function(thisValue) {
    var f = this;
    return function() {
        return f.apply(thisValue, arguments);
    };
};

Upvotes: 8

Related Questions