I am continually having to hold this
in a temp variable in order to access it in other functions. For example in the two methods below, I am holding this
in a that
variable:
startTimer: function () {
var that = this;
if ($('#defaultCountdown:hidden'))
$('#defaultCountdown').show('slow');
shortly = new Date();
shortly.setSeconds(sh开发者_开发百科ortly.getSeconds() + 5);
$('#defaultCountdown').countdown('change', { until: shortly,
layout: '<ul id="errorList"><li>Next update in <b>{snn}</b> {desc}</li></ul>',
description: 'seconds',
onExpiry: function () {
that.performUpdate();
}
});
},
performUpdate: function () {
var that = this;
this.message.fetch({
success: function () {
$('#calleesStatuses').html('');
that.callees.refresh(that.message.get("Callees"));
$('#defaultCountdown').hide('slow');
that.startTimer();
},
error: function (request, settings) {
that.killCountDown();
showErrorMessage(request.responseText)
}
});
},
Is there anyway around this or could I possibly use apply
?
ECMAScript 5 introduced Function.bind()
[docs], so it is only supported by newer browsers. An alternative implementation can be found in the documentation I linked to. If you include it in your code, you can use bind()
in the other (older) browsers too.
It lets you set the object this
should refer to in the function. So you could write:
performUpdate: function () {
this.message.fetch({
success: function () {
$('#calleesStatuses').html('');
this.callees.refresh(this.message.get("Callees"));
$('#defaultCountdown').hide('slow');
this.startTimer();
}.bind(this),
error: function (request, settings) {
this.killCountDown();
showErrorMessage(request.responseText)
}.bind(this)
});
},
I think that's the simplest way to do it. This is what I do (although I'm writing GWT code), to reference the this
of the wrapping function in an inner anonymous function.
Even if something like this.wrappingMethod.this
were/are possible, storing the the this
in a variable named according to your taste is a lot more readable (you could use a more descriptive name, ofcourse), and (still assuming you cold somehow reference the wrapping scope) it will be more robust since you could introduce another level without having to rewrite all the references.
No, there isn't. The value of this
will be different in the closure than it is in the scope that the closure is defined so the only way to make it cleaner is to define it on an object level so at least you only have to do it once per object, which it looks like you are already doing anyway.
Edit:
Strike out the "No there isn't" because bind
is a valid alternative and there are comparability implementation (see other answer). Although I personally think var self = this;
is cleaner and you only need to define it once per object but it is a matter of preference at this point.
I guess it's no comfort, but not really if the original this
is the only context in which you can execute functions like startTimer
and killCountdown
. What I'd recommend is giving it a more meaningful name, like timer
or something. Really, this
is just a convenient keyword for referring to the owner of whatever we're executing, and it should change as the owner changes. If "this/that" is becoming hard to read, the solution is to change the name from that
to something more semantically meaningful.
What you're doing is a standard pattern in JavaScript, except that it's traditional to use self
instead of that
. But you can use the bind()
method like this:
onExpiry: performUpdate.bind(this);
if you're working with a framework that extends the prototype of Function
to include it, or your Javascript interpreter is recent enough. (bind
creates the same sort of anonymous function behind the scenes, but is arguably less efficient since it has to deal with all sorts of special cases).
精彩评论