16

What's the modern and correct way to pass the this context to an anonymous forEach function?

function Chart() {

  this.draw = function(data) {
     data.forEach(function(value) {
       //do something with values
       console.log(this); //question: how to get Chart instead of global scope?
     )};
  });

};
Brian Tompsett - 汤莱恩
  • 5,195
  • 62
  • 50
  • 120
mtmacdonald
  • 11,747
  • 16
  • 57
  • 93

2 Answers2

30

Store the current this in some other variable in Chart like this

function Chart() {
    var self = this;
    this.draw = function(data) {
        data.forEach(function(value) {
            //do something with values
            console.log(self);
        });
    }
};

Also, you can pass the this like the following, as Array.prototype.forEach accepts this

arr.forEach(callback[, thisArg])

For example,

this.draw = function(data) {
    data.forEach(function(value) {
        //do something with values
        console.log(this);
    }, this); // Pass the current object as the second parameter
}
thefourtheye
  • 206,604
  • 43
  • 412
  • 459
  • I prefer to use `self` instead of `that`, which seems too ambiguous to me. – RB-Develop Apr 02 '14 at 14:13
  • Haha nice one :) Always seems like a personal preference these days, though. So it really depends on what you find comfortable to use. – RB-Develop Apr 02 '14 at 14:15
  • @RB-Develop My other side is Python, so I am also comfortable with `self` :) – thefourtheye Apr 02 '14 at 14:15
  • @thefourtheye thanks. Any comments on the difference between passing this and using bind (see my own answer)? – mtmacdonald Apr 02 '14 at 14:16
  • 1
    @MMacdonald Nothing much, except that [`Function.prototype.bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) will create a new function and I don't think that can access the enclosed variables (Not sure about this, have to check). BTW, +1 to you, that didn't strike me at first :) – thefourtheye Apr 02 '14 at 14:18
  • 1
    @MMacdonald Okay, just confirmed. It can even access the enclosed variables. So, the only difference is, it creates new function. – thefourtheye Apr 02 '14 at 14:35
  • @thefourtheye thanks for such an informed answer. – mtmacdonald Apr 02 '14 at 14:42
6

Adding in my own answer (use bind):

this.draw = function(data) {
   data.forEach(function(value) {
     //do something with values
     console.log(this); //question: how to get Chart instead of global scope?
   }.bind(this));
});
marverix
  • 5,984
  • 6
  • 31
  • 46
mtmacdonald
  • 11,747
  • 16
  • 57
  • 93