JavaScriptinheritance:Object.create vs new

在JavaScript中这两个例子有什么区别:

先决条件:

function SomeBaseClass(){ } SomeBaseClass.prototype = { doThis : function(){ }, doThat : function(){ } } 

inheritance示例A使用Object.create:

 function MyClass(){ } MyClass.prototype = Object.create(SomeBaseClass.prototype); 

inheritance示例B使用新的关键字

 function MyClass(){ } MyClass.prototype = new SomeBaseClass(); 

这两个例子似乎都是一样的。 你什么时候select一个呢?

还有一个问题:考虑下面的链接(第15行)中的代码,其中对函数自己的构造函数的引用存储在原型中。 为什么这是有用的?

mrdoob/three.js/blob/master/src/loaders/ImageLoader.html

摘录(如果你不想打开链接):

 THREE.ImageLoader.prototype = { constructor: THREE.ImageLoader } 

在你提到的问题中,你提到Both examples seem to do the same thing ,这完全不是真的,因为

你的第一个例子

 function SomeBaseClass(){...} SomeBaseClass.prototype = { doThis : function(){...}, doThat : function(){...} } function MyClass(){...} MyClass.prototype = Object.create(SomeBaseClass.prototype); 

在这个例子中,你只是inheritance了SomeBaseClass' prototype但是如果你的SomeBaseClass有一个属性

 function SomeBaseClass(){ this.publicProperty='SomeValue'; } 

如果你使用它像

 var obj=new MyClass(); console.log(obj.publicProperty); // undefined ​console.log(obj);​ 

obj对象不会像本例中那样拥有publicProperty属性。

你的第二个例子

 MyClass.prototype = new SomeBaseClass(); 

它执行constructor函数,创buildSomeBaseClass的实例并inheritance整个SomeBaseClass对象。 所以,如果你使用

  var obj=new MyClass(); console.log(obj.publicProperty); // SomeValue console.log(obj);​ 

在这种情况下,其publicProperty属性也可用于obj对象,如本例中所示 。

由于Object.create在某些旧浏览器中不可用,因此可以使用

 if(!Object.create) { Object.create=function(o){ function F(){} F.prototype=o; return new F(); } } 

上面的代码只是添加Object.create函数,如果它不可用,所以你可以使用Object.create函数,我认为上面的代码描述了什么Object.create实际上。 希望这会有所帮助。

这两个例子似乎都是一样的。

你的情况确实如此。

你什么时候select一个呢?

SomeBaseClass有一个函数体时,这个会被new关键字执行。 这通常不是打算 – 你只想build立原型链。 在某些情况下,甚至可能会导致严重的问题,因为您实际上实例化了一个对象,其私有作用域variables由所有MyClass实例共享,因为它们inheritance了相同的特权方法。 其他副作用是可以想象的。

所以,你通常应该更喜欢Object.create 。 然而,它在一些传统的浏览器中不被支持。 这就是你看到这个新手很频繁的原因,因为它往往没有(明显的)伤害。 也看看这个答案 。

如果按照预期使用Object.create() ,则区别将变得明显。 实际上,它完全隐藏了代码中的prototype单词,它将在底层完成这项工作。 使用Object.create() ,我们可以去

 var base = { doThis : function(){ }, doThat : function(){ } }; 

然后我们可以从这里扩展/inheritance其他对象

 var myObject = Object.create( base ); // myObject will now link to "base" via the prototype chain internally 

所以这是另一个概念,是一个更“面向对象”的方式。 实例中没有使用Object.create() “构造函数”。 但是,当然你可以在这些对象中创build并调用一个自定义的构造函数

使用Object.create()一个参数是, 混合 / *从其他对象inheritance*看起来更自然 ,而不是使用Javascript的默认方式

我不是Java脚本的专家,但这里是一个简单的例子来理解“Object.create”和“新”之间的区别。

第1步:创build具有一些属性和操作的父function。

 function Person() { this.name = 'venkat'; this.address = 'dallas'; this.mobile='xxxxxxxxxx' } Person.prototype.func1 = function () { return this.name + this.address; } 

步骤2:使用New关键字创build一个扩展到Person函数上面的子函数(PersonSalary)。

 function PersonSalary() { Person.call(this); } PersonSalary.prototype = new Person(); PersonSalary(); 

步骤3:使用Object.create关键字创build在Person函数之上扩展的第二个子函数(PersonLeaves)。

 function PersonLeaves() { Person.call(this); } PersonLeaves.prototype = Object.create(Person.prototype); PersonLeaves(); 

//现在检查两个子函数的原型。

 PersonSalary.prototype PersonLeaves.prototype 

这两个子函数都会链接到Person(父函数)原型,并且可以访问它的方法,但是如果使用new创build子函数,它将返回一个全新的对象,其中包含我们不需要的所有父属性,而且当您创build对象或函数使用“新”,执行父函数,我们不希望成为。

这里是外卖

如果你只是想在父函数中委托一些方法而不想创build一个新的对象,那么使用Object.create是最好的方法。