0

I think that I've missunderstood the use of the keyword 'this' in javascript. I can't get my head around why "this.box1" changes from [object Object] to [object HTMLDivElement] the second time the mainloop gets executed, and why the TypeError gets thrown?

"box1" is the html id for a div element in the html code, that is shaped like a square.

function GeoObject(id){
    this.name = id;
    this.object = document.getElementById(id);
    this.objectStyle = window.getComputedStyle(this.object);
    this.heightCenter = parseInt(this.objectStyle.height) / 2;
    this.widthCenter = parseInt(this.objectStyle.width) / 2;
    console.log(this.name + "'s heightCenter: " + this.heightCenter);
    console.log(this.name + "'s widthCenter: " + this.widthCenter);
}

GeoObject.prototype.setMiddle = function(){
    //console.log("In setmiddle, this.heightCenter: " + this.heightCenter);
    this.object.style.top = (window.innerHeight / 2) - this.heightCenter + "px";
    this.object.style.left = (window.innerWidth / 2) - this.widthCenter + "px";
    console.log(this.name + "'s top: " + this.object.style.top);
    console.log(this.name + "'s left: " + this.object.style.left);
}

function PlayGround(){
    this.box1 = new GeoObject("box1");
    console.log("PlayGround.box1 object: " + this.box1.object);
    console.log("PlayGround.box1 objectStyle " + this.box1.objectStyle);
}


PlayGround.prototype.update = function(){
    console.log("this.box1.object: " + this.box1.object);
    this.box1.setMiddle();
    that = this;
    requestAnimationFrame(that.update);
};

P1 = new PlayGround();
//console.log("P1.box1.object: " + P1.box1.object);
P1.update();

Output:

"box1's heightCenter:" 100                                main.js (row 21)
"box1's widthCenter:" 100                                 main.js (row 22)
"PlayGround.box1 object:" [object HTMLDivElement]         main.js (row 35)
"PlayGround.box1 objectStyle" [object CSS2Properties]     main.js (row 36)
"this.box1:" [object Object]                              main.js (row 41)
"box1's top": 197px                                       main.js (row 29)
"box1's left": 583px                                      main.js (row 30)
"this.box1:" [object HTMLDivElement]                      main.js (row 41)

TypeError: this.box1.setMiddle is not a function        main.js (row 42, col 4)
this.box1.setMiddle();
PandaDeTapas
  • 516
  • 1
  • 7
  • 16
  • 2
    try `that.update.bind(that)` – thefourtheye Mar 19 '15 at 13:26
  • `that` may also be `this` as you don't need `that = this` – Hacketo Mar 19 '15 at 13:27
  • @thefourtheye : That worked splendid, thanks! Wonder why my code didn't work though? – PandaDeTapas Mar 19 '15 at 13:31
  • Your `that` variable is accidently global. Use `var` (if you need the variable at all) – Bergi Mar 19 '15 at 13:32
  • @Bergi Oops, hadn't noticed that. I get the same error though if i don't use bind() – PandaDeTapas Mar 19 '15 at 13:34
  • 1
    @PandaDeTapas Check the question Bergi duped. It explains this elaborately. – thefourtheye Mar 19 '15 at 13:35
  • @thefourtheye : Done. I think I understand it now, the requestAnimationFrame is the window's method so the this keyword refers to the window object instead..kinda :P – PandaDeTapas Mar 19 '15 at 13:53
  • @PandaDeTapas Nope. The `this` insider `update` function will be `window`. – thefourtheye Mar 19 '15 at 13:54
  • @thefourtheye But what about my "that=this" assignment? 'that' always ponts to 'this' of the Playground.prototype right? Anyways I thought that requestAnimationFrame was passed the function that 'this.update' was assigned to so the 'this' inside the function became window... GAaah I will never understand this, I will have to re-read the post I guess. – PandaDeTapas Mar 19 '15 at 14:52
  • @PandaDeTapas Go through the [examples in MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this). It will help you understand better, – thefourtheye Mar 19 '15 at 14:56

0 Answers0