开发者

Stop holding 'this' in a temp variable

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).

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜