说明两种类型的继承之间的区别?
function inherit(c,p){
var F =function(){}
F.prototype=p.prototype;
c.prototype=new F();
}
AND
function inherit(c,p){
c.prototype=p.prototype;
}
如果有的话,各自的利弊是什么?
答案 0 :(得分:3)
在第二个中,c
和p
最终都使用相同的对象作为其prototype
属性。因此,向该对象添加内容会影响使用new c
和new p
创建的实例,因为这些实例从函数上的prototype
属性获取其基础原型。这是一个问题,孩子不应该像那样影响父母的实例。
例如,使用第二个,我们遇到了这个问题:
function Parent() {
}
function Child() {
}
inherit(Child, Parent);
Parent.prototype.question = "Life, the Universe, and Everything";
Child.prototype.answer = 42;
var par = new Parent();
var ch = new Child();
console.log(par.question); // "Life, the Universe, and Everything"
console.log(ch.question); // "Life, the Universe, and Everything"
console.log(par.answer); // 42 <=== WRONG, Parent instances don't have the property
console.log(ch.answer); // 42
上面的代码在内存中创建了这种情况(让我们使用一个名为__proto__
的属性来表示一个对象的底层原型;这就是即将发布的ES6规范所做的事情):
The second one: Wrong +-----------------+ | Function Parent | +-----------------+ +---------------+ | prototype |----+++-->| Object | +-----------------+ ||| +---------------+ ||| | question: ... | +------------+ ||| | answer: 42 | | Parent par | ||| +---------------+ +------------+ ||| | __proto__ |---------+|| +------------+ || || +-----------------+ || | Function Child | || +-----------------+ || | prototype |-----+| +-----------------+ | | +-----------+ | | Child ch | | +-----------+ | | __proto__ |------------+ +-----------+
使用第一个,c.prototype
是一个新的对象,其p.prototype
作为其基础原型。将内容添加到c.prototype
赢得会影响使用new p
创建的实例,只会影响使用new c
创建的实例。但是,向p.prototype
添加内容会影响两者,如果c
意图从p
继承,则有意义。
function Parent() {
}
function Child() {
}
inherit(Child, Parent);
Parent.prototype.question = "Life, the Universe, and Everything";
Child.prototype.answer = 42;
var par = new Parent();
var ch = new Child();
console.log(par.question); // "Life, the Universe, and Everything"
console.log(ch.question); // "Life, the Universe, and Everything"
console.log(par.answer); // undefined, Parent instances don't have the property
console.log(ch.answer); // 42
这在内存中设置了这个:
The first one +-----------------+ | Function Parent | +-----------------+ +---------------+ | prototype |----+---->| Object |<-+ +-----------------+ | +---------------+ | | | question: ... | | +------------+ | +---------------+ | | Parent par | | | +------------+ | | | __proto__ |---------+ | +------------+ | | +-----------------+ | | Function Child | | +-----------------+ +---------------+ | | prototype |------+-->| Object | | +-----------------+ | +---------------+ | | | __proto__ |--+ +-----------+ | | answer: 42 | | Child ch | | +---------------+ +-----------+ | | __proto__ |------------+ +-----------+
如果有的话,各自的利弊是什么?
第二个实际上是错误的。 : - )
附注:在启用ES5的环境中,第一个可以更简单:
function inherit(c,p){
c.prototype = Object.create(p.prototype);
}
附注2:为了更加彻底,第一个应该是这样的:
function inherit(c,p){
var F =function(){}
F.prototype=p.prototype;
c.prototype=new F();
c.prototype.constructor = c;
}
或者这个:
function inherit(c,p){
c.prototype = Object.create(p.prototype);
c.prototype.constructor = c;
}
从constructor
对象的Function
属性引用的对象的prototype
属性应该指向该函数。这是在规范中设置函数的方式,尽管它实际上并没有使用 constructor
属性。但是,有些人可能会使用它的代码,并希望规范的设置在那里。