How can I keep the context of 'this' in jq

2019-02-07 03:33发布

问题:

I have something like this:

var Something = function(){
  this.render = function(){};
  $(window).resize(function(){
    this.render();
  });
}

The trouble is that inside the anonymous function 'this' refers to the window object. I know I could do something like:

var Something = function(){
  this.render = function(){};
  var tempThis = this;
  $(window).resize(function(){
    tempThis.render();
  });
}

but is there a better way? This doesn't look very elegant.

回答1:

The solution you found is the the one most people use. The common convention is to call your tempThis variable "that."

var Something = function(){
  this.render = function(){};
  var that = this;
  $(window).resize(function(){
    that.render();
  });
};


回答2:

That looks like your best option, I don't think there's a better way. (someone correct my if I'm wrong).



回答3:

FYI the ability to control this is coming in the next version of JQuery



回答4:

I've been doing it this way in many tight situations. It doesn't look elegant, but it never fails. Actually thats javascript closures in action.

jrh



回答5:

That's exactly what I do. It's not specific to jQuery, either.

var Construct = function() {
    var self = this; //preserve scope

    this.materials = 2000;

    this.build = function(){
        self.materials -= 100;
    };
};

Remember to use the var keyword in front of your new scope variable. Otherwise, you're creating a new global variable. As a local variable, it will still be accessible inside the inner function via a closure.



回答6:

The best solution, to keep variables at a minimum would be to use the Function.prototype.bind() method.

var Something = function(){
  this.render = function(){};
  $(window).resize( this.render.bind( this ) );
}

The problem with this method that may cause future complications, which means you should choose to use it sparingly, is when you need to invoke $(this) to grab the element. So, I might suggest that it would be worthwhile to use Function.prototype.bind() in your resize method, but it would not be a good solution to use it in a click function that you might need to target the clicked element directly.

See this JSFiddle for a working example.

See the Mozilla Documentation on Function.prototype.bind() for more information

The other methods are usable, but creating a variable to maintain the context of this is the undesired effect according to your question.