简体   繁体   中英

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 the "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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM