0

I am trying to create a "class" in JS, a simplified structure of which is below:

http://codepen.io/Deka87/pen/WpqYRP?editors=0010

function Alert() {
  this.message = "Test alert";
  this.document = $(document);

  this.document.on('click', function() {
     this.show();
  }.bind(this));

};

Alert.prototype.show = function() {
  setTimeout(function() {
    console.log(this.message);
  }, 50);
};

var alert = new Alert();

When you click on the document it should show you the this.message contents in console. However, it is now shown as undefined. I believe the problem is that this.messsage can't get the original this context because it is wrapper in another function (setTimeout in my case). Any help would be appreciated!

sdvnksv
  • 9,350
  • 18
  • 56
  • 108
  • 1
    Possible duplicate of [Pass correct "this" context to setTimeout callback?](http://stackoverflow.com/questions/2130241/pass-correct-this-context-to-settimeout-callback) – Andreas Apr 08 '17 at 16:19
  • Seriously, you have `bind` right there in your code already... – Adam Jenkins Apr 08 '17 at 16:28

2 Answers2

0

Here's what worked for me, you get your this.message by referencing self, which is the correct context you need.

function Alert() {  
  this.message = "Test alert";
  this.document = $(document);
  this.document.on('click', function() {
  this.show();
}.bind(this));
};
Alert.prototype.show = function() {
  var self = this;
  setTimeout(function() {
    console.log(self.message);
  }, 50);
};
var alert = new Alert();
Lixus
  • 511
  • 2
  • 12
0

You can use arrow functions which will preserve your this context.

function Alert() {
  this.message = "Test alert";
  this.document = $(document);

  this.document.on('click', () => {
     this.show();
  });

};

Alert.prototype.show = function () {
  setTimeout(() => {
    console.log(this.message);
  }, 50);
};

var alert = new Alert();

Read more: https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Functions_and_function_scope/Arrow_functions.