开发者

How can I avoid using this snippet in Javascript closures?

I use this snippet in Javascript like 100 times a day to have a closure on the enclosing object:

Class.prototype.Method = function(arg){
    var Ta = this;
    var e = function(){
        Ta.doSomething(arg);
    };
};

it there a way to avoid the Ta variable and still refere to t开发者_Python百科he "outer" (is this word correct?) object?


I don't know that I'd advocate this as superior, but you could use ".bind()":

var e = function() {
  this.doSomething(arg);
}.bind(this);

That ensures that the this value inside function "e" will always be the this value of the surrounding context. The .bind() function is available in newer browsers, or via a polyfill like the one on the MDC site.

I rather like keeping those local variables around, especially in complicated functions that set up event handlers and stuff like that; it helps clarify the relationships between layers of code.


a) You could continue using this approach with more meaningful variable names. Using that is a common convention -- it's indicative that your variable is just another "this" value, but for another function scope.

b) You can use a function bind utility. Some JavaScript libraries come with one. Or you can simply roll your own:

function bind(fn, scope) {
    return function () {
        fn.apply(scope, arguments);
    };
}

// for your example:
Class.prototype.Method = function(arg) {
    var e = bind(function() {
        this.doSomething(arg);
    }, this);
};

// Alternatively, extend the Function prototype (may raise some eyebrows):

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

// for your example:
Class.prototype.Method = function(arg) {
    var e = function() {
        this.doSomething(arg);
    }.bind(this);
};

Update: As @Pointy noted, bind is actually part of a new version of the JavaScript spec, getting picked up by modern browsers already: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind


I don't believe there is. I do the same thing all the time.


I use a small home-made framework to easily use prototype inheritance, and in this framework I have about the same piece of code. I think there's no way to do without this.

Now the question is : Why not doing this ? do you think it's a bad practice, and why ?

The piece of code I use :

function getCallback(obj, methodName) {
    var method = obj[methodName];

    function callback() {
        if (obj[methodName] === callback) {
            return method.apply(obj, arguments);
        }
        return obj[methodName].apply(obj, arguments);
    }

    return callback;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜