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】:
它完全按照文档所述:
用指定的原型对象创建一个新对象并 属性。
本例中的proto
是Person
:
参数说明如下:
应该是新创建对象的原型的对象。
您的代码 Object.create( Person.prototype );
返回一个对象,该对象复制一个人的属性(在本例中为名字、姓氏和性别)并将它们分配给 SuperHero。
注意Person
和SuperHero
之间的相似之处,它们都包含firstName
和lastName
。还要注意区别,Person
包含 gender
属性,而您的 SuperHero
包含 powers
属性。
【讨论】:
Object.create
不会复制任何属性。使用Object.create(Person.prototype)
创建的对象将不具有Person
构造函数中分配的firstName
、lastName
和gender
属性。
但它甚至没有真正获得它们......除非它们被手动复制到对象中,在这种情况下,它位于 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();
我不喜欢具体链接原型,因为这意味着两个原型是交织在一起的,我更喜欢一个是子类,一个是超类。
自己查看它们的一个好方法是做这样的事情。在这里,您可以真正看到SuperHero
从Person
获得的继承。请注意,它具有所有属性(第一个/最后一个/等),并且是附加的权力。
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) 在这段代码中做了啥?的主要内容,如果未能解决你的问题,请参考以下文章