Thiago Arrais
Thiago Arrais

Reputation: 34180

How to pass 'this' along with a function?

I want to delegate some function calls from one object to another:

objA.feature = objA.component.feature;

(Assuming feature is supposed to be a function both in objA and in its component)

But that clearly doesn't work, because the reference to this gets stripped from the function and ends up being a completely different object when it gets called (it actually is objA instead of objB.component).

You need to write something like this in order to get it to work:

objA.feature = function() {
    objA.component.feature.apply(objA.component, arguments);
};

Is there a shorter (idiomatic) way to do that?

Upvotes: 3

Views: 167

Answers (3)

Pointy
Pointy

Reputation: 413702

There's a function called "bind" on the Function prototype in newer runtimes:

var newFunc = someFunc.bind(somethingThatShouldBeThis);

will make this refer to "somethingThatShouldBeThis" when "newFunc" is called.

You can steal code from something like the Functional library to provide a "bind" function in environments that lack a native one.

edit — here's the code from Functional:

Function.prototype.bind = function(object/*, args...*/) {
    var fn = this;
    var args = Array.slice(arguments, 1);
    return function() {
        return fn.apply(object, args.concat(Array.slice(arguments, 0)));
    }
}

Pretty simple, eh? It just returns a function back to you that, when invoked, will call the first argument as a function, and also pass along whatever arguments you pass in to the result (that is, to "newFunc" in the example above). The main wrinkle is that this one also saves extra arguments passed in originally, which can sometimes be handy.

Upvotes: 5

Brad Wilkie
Brad Wilkie

Reputation: 331

Here is a great article on scope:

Binding Scope in JavaScript

However, most JavaScript frameworks (MooTools, jQuery) have built in methods for this. jQuery uses "proxy" and MooTools uses "bind", so be sure to check the documentation of whatever framework you're using.

Upvotes: 1

Paul
Paul

Reputation: 36319

Your best bet is to use a createDelegate-style method like some of the frameworks do. A bare-bones implementation was posted on OdeToCode a few years ago.

Upvotes: 0

Related Questions