为什么我们使用构造函数的prototype属性添加方法?

时间:2016-12-05 18:04:25

标签: javascript constructor prototype

我不了解原型和构造函数。

假设我有这个构造函数,它将创建一个名为'的对象。财产和' logName'方法

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

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

我理解我刚刚在构造函数' s(myExample)原型中添加了一个方法(logName)。当我使用这个构造函数创建一个新对象(我)时,该对象将继承&#39 ;名称'财产和' logName'方法。 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

3 个答案:

答案 0 :(得分:6)

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

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

如果您想了解更多信息Advantages of using prototype, vs defining methods straight in the constructor?

,此问题会触及相同的主题

答案 1 :(得分:1)

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

相反,每个MyExample都有自己的函数副本。当实例数量增加时,它最终占用更多内存,如果由于某种原因你想在运行时修改所有 MyExample,你必须改变每个实例的功能而不是修改原型。

每个人都在看维基百科的相同“副本”,而不是将所有维基百科保存到他们的硬盘并阅读它的人之间的区别。它毫无意义地耗尽额外的硬盘空间,如果维基百科更新,每个人都错了,直到他们下载新版本。

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

答案 2 :(得分:0)

在原型中添加方法可以为代码提供更好的抽象。

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

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

这意味着你会浪费更多的记忆。