GG.
GG.

Reputation: 21854

Keep "this" in a variable and replace all "this" with this variable?

Context

When I use jQuery, I often need to keep this in a variable:

var obj = {
    myVar: null,
    myFunction1: function() { ... },
    myFunction2: function() {
        this.myVar = "blabla";
        this.myFunction1();

        var ctx = this;
        $('xxx').click(function () {
            ctx.myFunction1();
        });
    }
}

In this case, I replace all this with my variable:

var obj = {
    myVar: null,
    myFunction1: function() { ... },
    myFunction2: function() {
        var ctx = this;

        ctx.myVar = "blabla";
        ctx.myFunction1();

        $('xxx').click(function () {
            ctx.myFunction1();
        });

        //etc. I do it for all "this" even if I have 15 "this"...
    }
}

Questions

Upvotes: 2

Views: 757

Answers (5)

Fabrizio Calderan
Fabrizio Calderan

Reputation: 123397

Is there another way?

Yes: you could pass the reference to the scope with an anonymous self executed function

myFunction2: function() {
    this.myVar = "blabla";
    this.myFunction1();

    (function(outerscope) {
        $('xxx').click(function () {
            outerscope.myFunction1();
        });
    }(this));
 }

Anyway, storing a reference as you did is fine (or at least, it is not discouraged as a bad practice from google javascript style guide) and it is a widely used common practice.

Upvotes: 2

WickyNilliams
WickyNilliams

Reputation: 5308

It's generally an accepted pattern, but it can get confusing when you have functions within functions (within func-functions-tions ;-) etc

One way to mitigate this (and an alternative approach in general) is to bind your function to a specific context object. ECMAScript 5's bind() function handles this, but probably isn't safe to use in a web environment yet.

For now you can instead use jQuery's proxy function:

    $('xxx').click(jQuery.proxy(function () {
        this.myFunction1();
    }, this));

Upvotes: 1

Felix Kling
Felix Kling

Reputation: 816730

Is there another way?

You can use $.proxy [docs]:

$('xxx').click($.proxy(function () {
    this.myFunction1();
}, this));

which obviously overwrites this inside the event handler, so you don't have access to the element through this.

You can also pass this as event data [docs]:

$('xxx').click({ctx: this}, function (event) {
    event.data.ctx.myFunction1();
});

Do whatever you find most readable. I personally just assign var self = this; and use self inside nested functions and this everywhere else.

Upvotes: 2

Andrea Turri
Andrea Turri

Reputation: 6500

I use always to create:

var _self = this;

To be honest I don't know if it is a best practice but since I code in js I saw many people doing that and I feel comfortable in using that.

Upvotes: 1

Rene Pot
Rene Pot

Reputation: 24815

this is different in a different function. Context is different in that situation.

Therefore, it is smart to keep it in a separate variable so you know for sure what context you are talking to.

Within functions where there are sub-functions I recommend this, in a regular function just don't. There is no need there.

note: You don't replace it, you merely have a pointer to the correct context.

Upvotes: 3

Related Questions