以下是几种js中实现继承的方式方法,它们也是各自有各自的优缺点,选择哪一种根据自己的应用而定,最适合自己的才是最好的.
通过原型链继承
function SuperType(){
this.name = 'yahualingfeng';
}
SuperType.prototype.friends = ['David','Bob','Lucy'];
SuperType.prototype.sayName = function(){
alert(this.name);
};
function SubType(){
this.age = 30;
}
SubType.protoType = new SuperType();//通过原型对象继承SuperType
var subType1 = new SubType();
var subType2 = new SubType();
subType1.friends.push('Jake');
console.log(subType1.friends); // ['David','Bob','Lucy','Jake']
console.log(subType2.friends); // ['David','Bob','Lucy','Jake']
缺点:
- 引用类型的值在原型中会被所有实例共享.
- 不能向超类的构造函数中传递参数
借用构造函数继承
借用构造函数继承是将超类(SuperType
)所有的属性和方法都写在构造函数中,最后在函数(SubType
)体内通过call
方法调用超类.
function SuperType(){
this.name = 'yuhualingfeng';
this.friends =['David','Bob','Lucy'];
this.sayName = function(){
alert(this.name);
}
}
function SubType(){
SuperType.call(this);
}
var subType = new SubType();
subType.sayName();
缺点:方法的定义都存在构造函数中,导致函数无法被复用.
组合继承
组合继承是原型链继承和构造函数继承的结合体,结合了二者的优点,即实现了函数的复用,也不会导致引用类型值在多个实例中共享.
function SuperType(){
this.name='yuhualingfeng';
this.friends=['David','Bob','Lucy'];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
function SubType(){
SuperType.call(this);
}
SubType.prototype = new SuperType();
var subType = new SubType();
缺点:
- 超类函数被执行了两次.
- 超类构造函数
SuperType
自身的属性(name
,friends
)被重复定义,即出现在SubType
的构造函数中,也出现在SubType
的原型对象中.
原型继承
原型继承是继承自一个对象而不是引用类型.
function object(obj){
function F(){}
F.prototype = obj;
return new F();
}
这里的object方法接收obj对象,并将对象赋值给一个空函数的原型,并返回空函数的实例.
var person = {
name:'yuhualingfeng',
friends:['David','Bob','Lucy']
};
var anotherPerson = object(person);
anotherPerson.name = 'Jake';
anotherPerson.friends.push('Marry');
console.log(anotherPerson.friends); //['David','Bob','Lucy','Marry']
console.log(person.friends); //['David','Bob','Lucy','Marry']
如果不想创建构造函数,只想让一个对象和另一个对象保持一致的情况下,原型继承是完全可以胜任的,不过有一点要注意的是,假如继承的属性值为引用类型时,还是会相互影响的.
寄生继承
寄生继承是基于原型继承的基础上扩展自己的属性和方法.
function createrAnother(obj){
var clone = object(obj);
clone.sayHi=function(){
alert('Hi!');
}
return clone;
}
var person = {
name:'yuhualingfeng'
};
var anotherPerson = createAnother(person);
anohterPerson.sayHi(); // Hi
寄生继承也是和原型继承一样也是继承对象,并产出对象.
寄生组合继承
顾名思义,寄生组合继承是集寄生继承和组合继承的结合体,它结合了二者的优点.
//继承Supertype的原型对象
function inheritProtoType(SuperType,SubType){
var prototype = object(SuperType.prototype);
prototype.constructor = SubType;
SubType.prototype = prototype;
}
function SuperType(){
this.name = 'yuhualingfeng';
this.friends = ['David','Bob','Lucy'];
}
function SubType(){
////继承Supertype的构造函数属性
SuperType.call(this);
this.age = 30;
}
inheritProtoType(SuperType,SubType);
var subType = new SubType();
寄生组合继承是前面几种继承思想碰撞在一起的产物,是执行效率最高也是应用面最广的.
总结
原型链继承
是通过为原型对象赋值,不足之处为引用类型值会被多个实例共享,构造函数继承
解决了原型链继承
的问题,同时也暴露出新的问题是函数的复用无法实现,然后我们结合二者的优缺点,构造出了组合继承
,组合继承
基本上满足了我们想要的继承结果.
考虑到执行的效率,我们构思出了寄生继承
(基于原型继承),并将寄生继承
和组合继承
结合,最终得出了继承的最优解决方案'寄生组合继承
.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。