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;
}
精彩评论