JavaScript - referencing 'this' in an inne

2019-02-27 18:10发布

问题:

Consider the following code:

MyClass.prototype.my_func = function () {
    this.x = 10;
    $.ajax({
        // ...
        success: function (data) {
            alert(this.x);
        }
    });
}

It doesn't work, since apparently this is not bound into the closure's execution context. I've been able to work it around by introducing another variable:

var _this = this;

And this works inside the anonymous function. But looks quite ugly to me. Is there some nice way to handle this?

回答1:

This may look like the ugly solution for you and there are some walkarounds (such as using bind() method to change the context), but this is the best solution I know of.

Alternatively you can change it to:

var self = this;

or give it more meaningful name, but it would be better (in this case) not to change the context, as you may need it some day.



回答2:

You can make usage of Function.prototype.bind for that:

MyClass.prototype.my_func = function () {
    this.x = 10;
    $.ajax({
        // ...
        success: function (data) {
            alert(this.x);
        }.bind(this);
    });
}

Now the parent context variable is also bound to the anonymous function.



回答3:

the this syntax usually refers to the object, not a function. In your case, this refers to MyClass.

If you're using the variable in the object, you probably forgot to define x in MyClass.

If you're using the variable within the function ONLY I'd define my variables using the var syntax. Variables defined within a function are destroyed when a function ends.

MyClass.prototype.my_func = function () {
    var x = 10;

    $.ajax({
        // ...
        success: function (data) {
            alert(x);
        }
    });
}


回答4:

The closure will have access to all objects defined in its parent's context. So if we have:

function() {
  var x = 10;
}

Then this is valid:

function() {
  var x = 10;

  (function() {
    alert(2*x); // 20
  }())
}

Therefore, when you define var _this = this you have merely defined a new variable in the parent's context that is available within the closure. See question #4371333 for more information on this "pattern."