0

I have a constructor:

function Domino() {

var self = this;
this.myElement = $("#smth");

this.rotation = 0;
this.rotateFor = function (deg, scl) {
    this.rotation += deg;
    this.scale = scl;
    this.myElement.find(".domino-view").css({
        transform: "rotate(" + self.rotation + "deg)  scale(" + self.scale + ")"
    });
};

I want to set timeout on rotateFor. I tried this:

this.rotateFor = function (deg, scl) {
    this.rotation += deg;
    this.scale = scl;
    this.myElement.find(".domino-view").css({
        transform: "rotate(" + self.rotation + "deg)  scale(" + self.scale + ")"
    });
}
this.start = function(){
self.timeout = setTimeout(function(){this.rotateFor()}, 5000)

}

Then I call it like this: something.start(), but it still does not work. How can I set timeout in this constructor?

Петр
  • 3
  • 2
  • @JamesThorpe that's not the problem here, since the OP has correctly passed `this` in the callback. However he probably _hasn't_ passed the correct `this` when calling `self.timeout` in the first place. – Alnitak Apr 04 '16 at 14:37
  • @Alnitak That's what this dupe covers - the `this` contained within the callback passed to `setTimeout`? OP already has `self`, just needs to use it as per the dupe. – James Thorpe Apr 04 '16 at 14:39
  • You don't need to wrap the this.rotateFor call in a function. You can just write self.timeout = setTimeout(this.rotateFor, 5000); Although, bear in mind you are just setting what happens when you call timeout() here. You actually need to ensure that timeout() is called to make your rotateFor function fire. – ManoDestra Apr 04 '16 at 14:40
  • @Alnitak: He has *not* correctly passed `this` in the callback. It uses `this` instead of `self`, and is not bound. – Bergi Apr 04 '16 at 14:41
  • @ManoDestra I think the OP wants to be able to control when the `setTimeout()` begins, hence having it wrapped in a function. – Scott Marcus Apr 04 '16 at 14:41
  • Doesn't need it though, even in that instance. He's wrapping the rotateFor in an unnecessary anonymous function, which then just calls rotateFor. It's redundant. – ManoDestra Apr 04 '16 at 14:42
  • I wasn't talking about the anonymous function, I was talking about the `start` function. – Scott Marcus Apr 04 '16 at 14:47
  • @Bergi you're right - I'm jetlagged :( – Alnitak Apr 04 '16 at 14:49

3 Answers3

0

You are using self to create an instance variable and this in setTimeout where it won't refer to the right object instance.

function Domino() {

   var self = this;
   this.myElement = $("#smth");

   this.rotation = 0;
   this.rotateFor = function (deg, scl) {
       this.rotation += deg;
       this.scale = scl;
       this.myElement.find(".domino-view").css({
           transform: "rotate(" + self.rotation + "deg)  scale(" + self.scale + ")";
       });
   };

   this.start = function(){
      this.timeout = setTimeout(function(){
          // Here is where the self variable benefits you:
          self.rotateFor();
      }, 5000);
   }
 }
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
0

Firstly, self is not something which exists anywhere (within that scope). Secondly, this within the setTimeout function does not refer to the current object. You also need to call rotateFor within the correct context.

Use something like:

this.start = function(deg,scl){
    var self = this; //Must specify what self is.
    this.timeout = setTimeout(function(){ //This outside (self also works since we defined it)
          self.rotateFor(deg,scl); 
    }, 5000);
}

If you want to start the timeout within the constructor you can do the following:

function Domino() {

var self = this;
this.myElement = $("#smth");

this.rotation = 0;
this.rotateFor = function (deg, scl) {
    this.rotation += deg;
    this.scale = scl;
    this.myElement.find(".domino-view").css({
        transform: "rotate(" + self.rotation + "deg)  scale(" + self.scale + ")"
    });
};
setTimeout(function(){ 
    self.rotateFor(<p1>,<p2>); //Parameters needed
}, 5000);
apokryfos
  • 38,771
  • 9
  • 70
  • 114
  • `self` comes from `var self = this;`, it's fine. – Bergi Apr 04 '16 at 14:42
  • `self` is declared in the first code block, rather than the smaller copy that contains just the rotate function and the attempt to call it. – James Thorpe Apr 04 '16 at 14:42
  • Minor update. Need could pass the rotateFor parameters in the this.start function, otherwise I have no idea where you'll be getting them from. For the second case, no idea where you'll be getting them from in general. – apokryfos Apr 04 '16 at 14:46
0

you need to bind this:

setTimeout(function(){this.rotateFor()}.bind(this), 5000);