前面说了原型链、借用构造函数、组合式继承三种继承实现方式。其实组合式继承就是最常用的继承实现方式。现在继续说说剩下的三种。
原型式
跟原型链类似
function object(o){
function F(){};
F.prototype = o;
return new F();
}
//通过这样一个方法,把新对象赋值给一个函数的原型。
//而不是把实例化结果赋值给一个函数的原型,这点有别于原型链
var person = {
name:"chenqi",
friends:["siji","zhutou","ligui"]
};
var anotherPerson = object(person);
console.log(anotherPerson.name);
其实ECMAScript5有一个新的方法叫Object.create(),它规范了原型式继承,这个create方法接收两个参数,一个是新对象,另一个是新对象定义额外的属性对象(可选)。在传入第一个参数的情况下,Object.create()方法与之前编写的object()方法的行为相同。如下:
var person = {
name:"Nicholas",
friends:["shelby","court","van"]
};
var anotherPerson = Object.create(person,{
name:{
value:"greg"
}
})
console.log(anotherPerson.name);
优点:
不需要写构造函数,只是简单的把一个对象进行了简答的复制。
缺点:
这个大家是有目共睹的,除了没有写构造函数之外,其他的思路基本跟原型链式继承是一样的。所以我们在实例化的时候,给person.friends这个数组push进一个值,那么其他实例化对象也会随之多了一个friends值。因为我们得到的对象是在F()函数的原型上。其属性是共用的。
寄生式继承
这种方式我觉得好没劲。可能是我读的书少吧。没有意识到这种方式的优点。上代码:
function object(o){
function F(){};
F.prototype = o;
return new F();
}//对新对象进行复制
function createAnother(original){
var clone = object(original)//先把新对象复制一下
clone.sayHi = function(){//然后又给新对象的副本添加方法
console.log("hi");
};
return clone;
}
var person = {
name:"chenqi",
friends:["shelby","court","van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi();
优点:
跟那个原型式继承一样,不需要写构造函数,只是简单地对一个对象的复制。
缺点:
对复制完的对象添加的方法写到了createAnother函数里面,不利于函数的复用。这个缺点跟之前的借用构造函数的缺点类似。
我觉得这种方式并没有什么卵用。
像刚才的那段代码,红圈里的那个给新对象添加方法的这段代码完全可以放到外面啊。或许正是这种种的原因,导致这种方式用的很少吧,个人觉得如果只是对一个对象的简单复制(不需要写构造函数的)就用原型式继承就好。
寄生组合式继承
这种方式牛逼就牛逼在他不用调两次父级构造函数。还记得组合继承吗。他的败笔就是把父函数的属性先放到了子函数的原型上,又啰啰嗦嗦的把父函数的属性放到了自己的构造函数里。
function object(o){
function F(){};
F.prototype = o;
return new F();
}//不多说,实现对象复制的。
function inheritPrototype(child,parent){
var prototype = object(parent.prototype);
prototype.constructor = child;
child.prototype = prototype;
}//这是关键,我觉得这个函数跟object函数加起来就实现了
//“子函数原型”对“父函数原型”的继承,
//跟组合继承的那句child.prototype = new parent();有异曲同工之妙。
function parent(name){
this.name = name;
this.colors = ["red","blue","green"];
}
parent.prototype.sayname = function(){
alert(this.name);
}
function child(name,age){
parent.call(this,name);
this.age = age;
}//这个自然就是子函数对父函数属性的继承
inheritPrototype(child,parent);
child.prototype.sayage = function(){
console.log(this.age);
}
var someone = new child("chenqi","18");
someone.sayage();
据说最常用的还是组合继承,我觉得也是组合式继承最顺,虽然他有缺点。瑕不掩瑜吧。