这两种原型继承实现之间的区别是什么?

shm*_*uli 5 javascript inheritance prototype prototypal-inheritance

这两个原型继承实现之间有什么区别,并且考虑到我们正在使用2个不同的"原型"(仅在函数和内部原型上的原型属性),以及这些实现在原型链查找中有何不同?另外,第一个实现(使用prototype属性)是否依赖于我们对new运算符的使用?

分配给函数的prototype属性并使用new运算符:

function foo() {}

foo.prototype.output = function(){
   console.log('inherits from Function.prototype property');
};

bar = new foo();
bar.output();
Run Code Online (Sandbox Code Playgroud)

将函数存储在对象文字中并使用该Object.create()方法:

var foo = {
  output: function(){
    console.log('inherits from the internal prototype');
  }
};

var bar = Object.create(foo);
bar.output();
Run Code Online (Sandbox Code Playgroud)

Kyl*_*yll 3

主要区别在于其使用方式以及相关的危险。

new第一个强制您在想要创建新对象时使用。该语法相当丑陋 ( ),并且它有一个主要缺陷:调用添加属性 ( ...)SomeConstructor.prototype.method的构造函数,而不会将构造应用于全局对象。构造函数的行为很奇怪(创建委托给的新对象,然后将构造函数应用于新对象,然后如果构造函数返回某些内容,则用某些内容替换该对象)。另外,在您的示例中,它本身不可用,您必须创建一个新对象才能访问其功能。this.name = nameParamnewSomeConstructor.prototypefoo

第二个,Object.create,不会强迫您使用任何合成怪癖。你没有全球污染的风险。该对象foo具有无需创建新对象即可使用的功能,并且bar将简单地借用这些功能。如果需要的话,这种模式还可以更容易地实现工厂(无需new到处替换)和对象池。

Eric Eliott 对此谈得很好Kyle Simpson 写了一本关于原型委托的书!

现在,查找是如何发生的:

  • 使用构造函数,查找是在Constructor.prototype(不是构造函数的实际prototype内部原型,而是其属性。如果您发现它令人困惑,那么恭喜您,您是人类)完成查找。其他属性在构造函数中设置。foo本身不用于查找,foo.prototype(再次,与指向 Function 的指针不同foo.__proto__)是用于查找的。
  • 查找Object.create是在对象本身上完成的 ( foo)。prototype对象上没有非原型属性。

凯尔·辛普森 (Kyle Simpson) 的书的这一页上有非常有趣的图表,进一步解释了这一点。

更多关于new这个问题:JavaScript 的“new”关键字被认为是有害的吗?