【问题标题】:JS what is the difference of methods defined inside and outside of the constructor functionJS构造函数内外定义的方法有什么区别
【发布时间】:2018-10-16 07:44:01
【问题描述】:

我有这个类对象,它需要在构造函数内部有它的绘制函数来更新分数,如果它在分数之外返回未定义。

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);
      }
   }
}

我的其他类对象在构造函数之外具有绘图功能,就像这样可以正常工作,

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();
}
}

我的问题是两者之间的区别是什么。我认为如果它在构造函数中定义,则变量可以在整个类对象中访问。我想我很困惑,构造函数之外应该有函数吗?将所有内容都放在构造函数中似乎很轻松。

【问题讨论】:

  • 泛型方法放在类体中,而自己的需要闭包的方法放在构造函数中。它可以节省内存和 CPU 开销来定义通用(原型)方法,而不是为每个对象实例实例化单独的函数实例。在类中说明方法也可以更清晰,更易于阅读。
  • 当在原型上声明类方法时(例如在构造函数之外),只有该函数的一个实例存在并被所有类实例重用,例如Ball.prototype.draw === ball1.draw === ball2.draw。当在实例上声明方法时(例如在构造函数内部),会为每个实例创建一个新函数,例如 ball1.draw !== ball2.draw.

标签: javascript


【解决方案1】:

在类中定义的函数(不是在构造函数中)存在于每个实例链接到的类原型上。构造函数中定义的函数成为每个实例自己的属性。如果你在构造函数中定义了函数,每个实例都会得到它自己的函数副本。如果您不这样做,实例将遵循原型链,并且所有实例都将指向同一个函数。例如:

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()

【讨论】:

  • 访问隐藏属性。方法调用的速度。对象足迹。取自这里:thecodeship.com/web-development/…
  • @zxxz 你能详细说明对隐藏属性的访问吗?
  • 与其说是“隐藏属性”,不如说是在构造函数中定义的局部变量。任何作用于构造函数的变量都不能被原型方法访问,但可以被定义在构造函数本身范围内的函数访问。因此,构造函数中的局部变量从类/对象的任何其他地方“隐藏”。
猜你喜欢
  • 2021-01-08
  • 2019-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-23
  • 1970-01-01
  • 1970-01-01
  • 2011-04-16
相关资源
最近更新 更多