Object.create(Class.prototype) 在这段代码中做了啥?

Posted

技术标签:

【中文标题】Object.create(Class.prototype) 在这段代码中做了啥?【英文标题】:What does Object.create( Class.prototype ) do in this code?Object.create(Class.prototype) 在这段代码中做了什么? 【发布时间】:2012-09-04 16:58:17 【问题描述】:

我正在阅读有关mixin pattern in javascript 的内容,并且遇到了这段我不明白的代码:

SuperHero.prototype = Object.create( Person.prototype );

原来的代码实际上有一个错字(大写的H)。如果我小写它,它会起作用。但是,如果我真的删除该行,一切似乎都一样。

这里是完整的代码:

var Person =  function( firstName , lastName )
  this.firstName = firstName;
  this.lastName =  lastName;
  this.gender = "male";
;

// a new instance of Person can then easily be created as follows:
var clark = new Person( "Clark" , "Kent" );

// Define a subclass constructor for for "Superhero":
var Superhero = function( firstName, lastName , powers )

    // Invoke the superclass constructor on the new object
    // then use .call() to invoke the constructor as a method of
    // the object to be initialized.

    Person.call( this, firstName, lastName );

    // Finally, store their powers, a new array of traits not found in a normal "Person"
    this.powers = powers;
;

SuperHero.prototype = Object.create( Person.prototype );
var superman = new Superhero( "Clark" ,"Kent" , ["flight","heat-vision"] );
console.log( superman ); 

// Outputs Person attributes as well as powers

SuperHero.prototype = Object.create( Person.prototype ); 是做什么的?

【问题讨论】:

不动产:***.com/questions/2449254/… 【参考方案1】:

它创建一个继承自 Person 构造函数的原型对象的新对象。

就像你这样做一样。

SuperHero.prototype = new Person();

除了它创建Person 实例而不实际调用Person 构造函数中的代码。

这个对象被用作SuperHero构造函数的原型对象,这样当你创建一个SuperHero实例时,它会继承Person的所有原型属性,以及任何直接添加到的原型属性SuperHero 原型对象。

【讨论】:

啊,所以如果有Person.prototype.die = function()... 我可以做superhero.die() 吗? @Duopixel:没错。 :) 原型链会按照object -> SuperHero.prototype -> Person.prototype -> Object.prototype -> null;的顺序搜索 @graystateiscoming +1 btw - 快速问题:“没有实际调用 Person 构造函数中的代码”。这部分让我失望,你这是什么意思? @mcpDESIGNS:在 ECMAScript 3 中,您只能通过调用构造函数来创建自定义对象。因此,要创建Person,您需要使用new 调用Person 函数,如var p = new Person()。但是在 ECMAScript 5 中,我们得到了Object.create,它允许我们创建一个与使用new 创建的对象具有完全相同的原型链的对象,只是我们不需要实际调用Person 函数。如果我们想要一个没有构造函数副作用的普通 Person 对象,这很有用。 @mcpDESIGNS:今天就使用它! :) jsfiddle.net/KAtmJ 这是一个垫片,可以让您做几乎相同的事情。它不支持Object.create 的第二个参数,并且不允许您使用null 作为原型对象,但它允许您创建从指定原型继承的对象。享受! :)【参考方案2】:

它完全按照文档所述:

用指定的原型对象创建一个新对象并 属性。

本例中的protoPerson

参数说明如下:

应该是新创建对象的原型的对象。

您的代码 Object.create( Person.prototype ); 返回一个对象,该对象复制一个人的属性(在本例中为名字、姓氏和性别)并将它们分配给 SuperHero。

注意PersonSuperHero 之间的相似之处,它们都包含firstNamelastName。还要注意区别,Person 包含 gender 属性,而您的 SuperHero 包含 powers 属性。

【讨论】:

Object.create 不会复制任何属性。使用Object.create(Person.prototype) 创建的对象将不具有Person 构造函数中分配的firstNamelastNamegender 属性。 但它甚至没有真正获得它们......除非它们被手动复制到对象中,在这种情况下,它位于 SuperHero 构造函数中,其中 Person.call(this, firstName, lastName); Person 函数将直接分配它们。但它不是来自Object.create(Person.prototype),因为这些属性没有原型。 @graystateiscoming 他们继承了这些属性。 不,属性不是继承的。由于Person.call(this...) 调用,它们被直接分配给对象。【参考方案3】:
SuperHero.prototype = Object.create( Person.prototype );

这基本上是让SuperHero 继承Person 的所有属性/原型。它与使用 new 几乎相同,但采用新的 ECMAScript 5 *Object.create()` 方式。也可以这样写,如果有助于理解的话。

SuperHero.prototype = new Person();

我不喜欢具体链接原型,因为这意味着两个原型是交织在一起的,我更喜欢一个是子类,一个是超类。

自己查看它们的一个好方法是做这样的事情。在这里,您可以真正看到SuperHeroPerson 获得的继承。请注意,它具有所有属性(第一个/最后一个/等),并且是附加的权力。

jsFiddle demo

var person = new Person();
SuperHero.prototype = person; // inheritance here
// the Object.create way is ECMAScript 5 (which not all browsers support yet sadly)

var superman = new SuperHero( "Clark" ,"Kent" , ["flight","heat-vision"] );
console.log( person );
console.log( superman ); ​

【讨论】:

以上是关于Object.create(Class.prototype) 在这段代码中做了啥?的主要内容,如果未能解决你的问题,请参考以下文章

Object.create()和new object()和{}的区别

浅谈Object.create

Object.create

js Object.create 初探

Object.create 方法

Object.create(null)