1

The properties x,y,width,height are not being read! When I do .drawImage(), this.x, this.y, this.width, this.height are not being used!

Say I changed the x the image won't change its position. However, if I alert(this.x) or any variable, then it will print out the correct value.

Thanks for the community help!

var Enemy = function(word, x, y, width, height) {

  this.word = word;

  //Position of the Enemy Spawn
  this.x = x;
  this.y = y;
  this.width = width;
  this.height = height;
}
Enemy.prototype.draw = function() {
  var image = new Image();
  image.onload = function() {
    Context.context.drawImage(image, this.x, this.y, this.width, this.height)
  };
  image.src = "enemy.png"
  // If I do alert(this.x), it returns the correct value!!!
}

This is the initialization:

var myEnemy = new Enemy("TestEnemy", 100, 100, 100, 100);
myEnemy.draw();

Entitize
  • 4,553
  • 3
  • 20
  • 28
  • 1
    There are many, many questions here on the same subject, e.g. [*How do JavaScript closures work?*](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work/111200?s=1|3.8197#111200), [*How do JavaScript closures work?*](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work/111111?s=3|2.1730#111111) (yes, two questions with identical subjects and over 4,500 votes between them), [*How does 'this" work in closure?*](http://stackoverflow.com/questions/25470907/how-does-this-work-in-closure) and many, many more. – RobG Oct 07 '15 at 02:33
  • You are correct @RobG but unless you've never heard of closures, how do you now how to ask about them? If you can outline what the issue is and point people in the right direction, then that's how they can then read up on them and then begin to understand what they are and how to use them. – Steven Anderson Oct 07 '15 at 02:40
  • UPDATE: I used var self = this Update: When I replace everything with self. When I call the function, it does not execute! Thanks for your help! – Entitize Oct 07 '15 at 03:41

2 Answers2

2

Your problem is related to how you are using this. You refer to this.x within the image.onload = function(). As this is resolved in the current execution context, in this case this will refer to the image being loaded. As you need to refer to this as the Enemy you can make a variable reference to maintain the context of the Enemy:

Enemy.prototype.draw = function(){
  var image = new Image();
  var self = this;
  image.onload = function() {
    Context.context.drawImage(image, self.x, self.y, self.width, self.height);
  };
  image.src = "enemy.png";
}

When you do alert(this.x) you will get the correct value as the scope from where you are calling it is correct. To see this in action add the following code and look at the results in your browser dev tools:

var self = this;
image.onload = function() {
  console.log(this);
  console.log(self);
}  
Steven Anderson
  • 8,398
  • 4
  • 27
  • 32
  • Note that *this* is always resolved in the current execution context and is set by the call (i.e. it's dynamic) or use of *bind*, not on the scope chain (which is lexical), therefore it is **not a scope issue**, it's a "how the function is called" issue that can be resolved by maintaining a reference to *this* at a point that its value is known to be the one required using a closure. Note that arrow functions are a little different, they set their *this* to the outer execution context's *this*, so can also be used to avoid issues like the OPs. – RobG Oct 07 '15 at 02:25
  • Hey @RobG so what would be the correct term to use to describe this (non) scoping issue? – Steven Anderson Oct 07 '15 at 02:30
  • It's a misunderstanding of how *this* is resolved, and not realising that it's always resolved in the current execution context and never on the scope chain (arrow functions are kind of an exception, but are still dependent on how their outer context's *this* is set). – RobG Oct 07 '15 at 02:39
  • UPDATE: When I replace everything with self. When I call the function, it does not execute! Thanks for your help! – Entitize Oct 07 '15 at 03:39
0

The context under image.onload event is under image not of instance of Enemy.

For you to access x, y, width, and height, you need to store instance to some variable like:

Enemy.prototype.draw = function() {
  var image = new Image();
  var self = this;
  image.onload = function() {
    Context.context.drawImage(image, self.x, self.y, self.width, self.height);
  };
  image.src = "enemy.png";    
}