【问题标题】:Why do we add methods using the prototype property of the constructor function?为什么我们要使用构造函数的原型属性来添加方法?
【发布时间】:2017-04-20 05:09:59
【问题描述】:

我不理解原型和构造函数的一件事..

假设我有这个构造函数,它将创建一个具有“name”属性和“logName”方法的对象

function MyExample(param1){
  this.name = param1;
};

MyExample.prototype.logName = function(){
  console.log(this.name);
}

我知道我刚刚在构造函数的 (myExample) 原型中添加了一个方法 (logName)。所以当我使用这个构造函数创建一个新对象 (我) 时,该对象将继承 'name' 属性和 '日志名称'方法。 logName 方法将成为新对象(我)的 proto 属性

的一部分
var me = new MyExample('bob');
me.logName(); //bob

..但是为什么不将 logName 方法添加到构造函数正在创建的对象中呢? (不是构造函数的原型)那不会提供相同的结果吗?即使 'logName' 不会成为新对象的 proto 属性的一部分。

function MyExample(param1){
   this.name = param1;
   this.logName = function(){
      console.log(this.name)
   };
};

var me = new MyExample('bob');
me.logName(); //bob

【问题讨论】:

    标签: javascript constructor prototype


    【解决方案1】:

    在原型中添加方法可以让您的代码更好地抽象。

    例如,由于方法与实例无关,因此您可以在足够兼容的非实例上调用它们。像这样:

    Array.prototype.slice.call({0:'a', 1:'b', length:2}); // ["a", "b"]
    

    如果你只在实例上定义你的方法,就需要创建一个无用的实例来借用方法:

    [].slice.call({0:'a', 1:'b', length:2}); // ["a", "b"]
    

    此外,在构造函数中定义一个方法意味着每个实例将收到不同的副本。

    new MyExample('bob').logName === new MyExample('bob').logName // false
    

    这意味着你会浪费更多的内存。

    【讨论】:

      【解决方案2】:

      在构造函数中创建方法的问题是它没有在MyExample 的所有实例之间共享。

      相反,每个MyExample 都有自己的函数副本。随着实例数量的增加,它最终会占用更多内存,如果由于某种原因您想在运行时修改 all MyExamples,则必须更改每个实例函数而不是修改原型。

      这是每个人都在查看维基百科的同一个“副本”与每个人都将所有维基百科保存到他们的硬盘驱动器并阅读它之间的区别。它毫无意义地占用了额外的硬盘空间,如果更新了 Wikipedia,那么在下载新版本之前,每个人都是错误的。

      如果由于某种原因您需要一个跨实例非常相似但每个实例略有不同的函数(例如,使用闭包变量),那么在构造函数中创建方法可能是正确的方法。

      【讨论】:

        【解决方案3】:

        在第二个示例中,每次创建 MyExample 的新实例时,都会重新创建 logName 函数。如果您使用MyExample 的原型,那么一个logName 方法将在MyExample 对象的所有实例之间共享,并且上下文会自动传递。

        原型还允许您在以后添加一个新方法,该方法可以被该类型的现有对象访问,或者全局修改一个类型的所有对象的方法。

        如果您想了解更多信息,此问题涉及同一主题,Advantages of using prototype, vs defining methods straight in the constructor?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-10-16
          • 1970-01-01
          • 2012-01-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多