1

I've made a prototype class of Bot. My issue is, after I've created it, I call it's init(). It correctly returns this value "a 5000" in an alert. However when that prototype function calls getUpdates() it no longer reaching the this value and giving "b undefined". I've even tried this.self = this; in the constructor but no luck.

After struggling, I've found adding () on the self.getUpdates call in the setInterval made it get the value properly then a another problem, setInterval only loops once. I've tried making a setTimeout and making it call itself inside getUpdates but got "too much recursion script.js:30:1". I've sometimes got "uncaught exception: out of memory "

I was originally using "var privateVars <-> this.methods" without much issue but switched to "this.publicVars <-> Class.prototype.methods" since I've read they supposed to be faster and less memory but this prototype method giving me issues. I've tried browsing Google but no luck. I would prefer to have timer start on init().

Here is my code:

var Bot = function () {
    "use strict";
    this.updateInterval = 5000;
    this.updateTimer = null;
};
Bot.prototype.getUpdates = function () {
    "use strict";
    var self = this;
    alert("b " + self.updateInterval); // returns "b undefined"
};
Bot.prototype.init = function () {
    "use strict";
    var self = this;
    $.get(/* pretend url is here*/, function (data, status) {
        alert("a " + self.updateInterval); // returns "a 5000"
        self.updateTimer = setInterval(self.getUpdates, self.updateInterval);
    });
};
window.bot = new Bot();
window.bot.init();

Any help or advice would be appreciated. But I'm thinking prototype isn't the way to go if it includes timers.

rai nalasa
  • 849
  • 1
  • 12
  • 32
Nova
  • 2,000
  • 3
  • 14
  • 24

3 Answers3

2

You have to bind the this context properly to the function reference,

self.updateTimer = setInterval(self.getUpdates.bind(self), self.updateInterval);

If you do not bind the context explicitly then the this context inside of getUpdates would point to window. So window.updateInterval will be undefined.

Rajaprabhu Aravindasamy
  • 66,513
  • 17
  • 101
  • 130
0

You can use bind to set the this context in your getUpdates function:

self.updateTimer = setInterval(self.getUpdates.bind(self), self.updateInterval);

Working example

Razzi Abuissa
  • 3,337
  • 2
  • 28
  • 29
0

You can send the this reference of Bot to the getUpdates function.

Bot.prototype.getUpdates = function (self) {
    "use strict";
    alert("b " + self.updateInterval); 
};
Bot.prototype.init = function () {
    "use strict";
    var self = this;
    $.get(/* pretend url is here*/, function (data, status) {
        alert("a " + self.updateInterval);
        self.updateTimer = setInterval(self.getUpdates(self), self.updateInterval);
    });
};
Ramin
  • 197
  • 8
  • Both @Rajaprabhu Aravindasamy and @Razzi Abuissa answers helped solve the issue, didn't expect a reply so quick, thanks. However, @Ramin answer didn't work, setInterval only triggered once for me but thanks for trying. Are there any other ways to access the class's prototype methods and this values like a set root without it assuming `window`? Say inside multiple functions are called but still knowing were `this` refers to or if possible without it? – Nova May 11 '16 at 17:27
  • That is right @Nova, the best way is how Rajaprabhu and Razzi has suggested so there would be no overhead of sending the Bot function reference to all other functions. Thumbs up for them. However for your case if you want to access the Bot function reference from anywhere then you can assign its reference to a variable in window object like this `window.botReference = this;` inside the Bot function. – Ramin May 12 '16 at 03:29