Wolf_Tru
Wolf_Tru

Reputation: 563

JS what is the difference of methods defined inside and outside of the constructor function

I have this class object that needs to have its draw function inside the constructor to update the score, if it is outside the score returns undefined.

export class Hud {
constructor(world) {
    var self = this;
    this.canvas = world.canvas;
    this.ctx = world.ctx
    this.score = 0;
    this.draw = function() {
        this.ctx.font = "16px Arial";
        this.ctx.fillStyle = "#0095DD";
        this.ctx.fillText("Score: " + self.score, 8, 20);
      }
   }
}

my other class objects have the draw function outside of the constructor like so works fine,

export class Ball {
constructor(world) {
    var self = this;
    this.canvas = world.canvas;
    this.ctx = world.ctx;
    self.x = canvas.width / 2;
    self.y = canvas.height - 30;
    this.ballRadius = 10
    this.dx = 2;
    this.dy = -2
}
draw() {
    this.ctx.beginPath();
    this.ctx.arc(this.x, this.y, this.ballRadius, 0, Math.PI * 2);
    this.ctx.fillStyle = "#0095DD";
    this.ctx.fill();
    this.ctx.closePath();
}
}

My question is what the difference between the two are. I thought if its defined in the constructor the variables are accessible throughout the class object. I guess I'm confused, should there be functions outside of constructor function? Having everything in the constructor seems to be hassle free.

Upvotes: 7

Views: 2024

Answers (1)

Mark
Mark

Reputation: 92440

Function defined in the class (not in the constructor) live on the class prototype which each instance is linked to. Functions defined in the constructor become own properties of each instance. If you defined the function in the constructor, each instance will get its own copy of the function. If you don't the instances will defer to the prototype chain and all the instances will point to the same function. For example:

class Hud {
    constructor(world) {
        this.name = world
        this.draw = function() {
            console.log("draw on instance from", this.name)
          }
       }
    draw_outside(){
        console.log("draw on class from", this.name )
    }
}

let h1 = new Hud('h1')
let h2 = new Hud('h2')

console.log(h1.__proto__.draw)         // draw not on prototype
console.log(h1.__proto__.draw_outside) // draw_outside is

console.log(h1.draw === h2.draw)                  // each object gets its own draw
console.log(h1.draw_outside === h2.draw_outside)  // but both point to the same draw_outside

console.log(Object.getOwnPropertyNames(h1))       // only draw & name

// both access `this` the same way when called on an instance:

h1.draw()
h1.draw_outside()

Upvotes: 7

Related Questions