【问题标题】:Why are methods always added to the prototype and not defined in the constructor function? [duplicate]为什么方法总是添加到原型中而不是在构造函数中定义? [复制]
【发布时间】:2016-06-12 23:33:37
【问题描述】:

大多数 JavaScript 指南使用构造函数来解释对象创建如下:

let Person = function (fn, ln) {
    this.fn = fn;
    this.ln = ln;
};
Person.prototype.greet = function () {
    console.log("hello "+ this.fn+ " "+ this.ln)
};

即:在构造函数中定义字段,在原型中添加方法。

现在我知道构造函数内部定义的属性将为 N 个实例形成 N 个副本,而原型上的属性将在所有 N 个实例之间共享 1 个副本。因此,在构造函数中定义属性是有道理的,因为我们显然不希望副本共享数组等可变属性。

我不明白为什么这些方法也没有在构造函数中定义。像这样:

let Person = function (fn, ln) {
    this.fn = fn;
    this.ln = ln;
    this.greet = function () {
       console.log("hello "+ this.fn+ " "+ this.ln)
    };
};

我知道这将导致每个实例和属于对象本身而不是其父/原型的方法都有一个副本,但它有什么特别的缺点吗?

在风格方面,它看起来更加连贯和类似于 Ruby 等。

【问题讨论】:

  • 提示:如果我执行Person('a','b').greet()this 在执行greet 期间指的是什么?
  • 重用存储在Person.prototype.greet 中的函数肯定比构造函数中定义的函数更容易。
  • 您能否详细说明如何更轻松地在prototype.greet 中重新使用该函数?所以你是说当Person的原型设置为子类时,构造函数内部设置的属性不会被继承?
  • 我的意思是,someotherconstructor.prototype.greet = Person.prototype.greetsomeotherconstructor.prototype.greet = new Person().greet 更容易,因为它不需要创建实例来访问/覆盖函数。
  • 这样看。无论哪种方式,您都可以这样做,并且有解决方法可以通过这两种解决方案实现您想要的任何目标。您已经提到了在构造函数中定义函数的主要问题,如果这对您来说不是问题,那就去做吧。

标签: javascript object constructor prototype


【解决方案1】:

因为如果我们在构造函数中定义方法,即使方法具有相同的代码,也会为每个对象创建一个新的Function 对象。

对象的数据成员是另一回事,因为它们应该携带每个对象唯一的数据。

【讨论】:

  • 是的,我知道。所以它只是为了节省内存?
  • 是的,也是因为它导致代码重用是oop的重要组成部分
  • 能否详细说明代码复用部分?我认为它的意思是在构造函数中定义的属性不会被“继承”给子类
猜你喜欢
  • 2014-01-11
  • 1970-01-01
  • 2011-10-30
  • 2015-06-10
  • 2012-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多