前置阅读:理解原型、new、构造函数
构造函数直接实现
function SuperType(){
this.property =true;
}
function SubType(){
SuperType.call(this);
}
//修改父类上的原型内容
SuperType.prototype.getType = function(){
return 'add';
}
var instance = new SubType();
console.log(instance.property);
//true
console.log(instance.getType());
//报错:Uncaught TypeError: instance.getType is not a function
- 问题:通过构造方法继承的子类,可以获取到父类构造函数当中的所有属性。
- 子类就无法获取到父类
prototype
上变化的属性和方法。 - 不好进行函数复用
- 子类就无法获取到父类
原型继承
function SuperType(){
this.property =true;
this.colors = ['red','green'];
}
SuperType.prototype.getSuperValue = function(){
return this.property;
}
var parent = new SuperType();
function SubType(){
this.property = false;//子类重写父类属性
}
//把子类的原型设置为父类的一个新的实例对象
//父类的实例的__proto__中指向它自己的原型对象
//所以这样子类也可以成功访问到
SubType.prototype = new SuperType();
SubType.prototype.getSubType = function(){
return this.property;
}
var instance = new SubType();
console.log(instance.getSuperValue());//false
instance.colors.push('blue');
console.log(parent.colors);//'red','green',
var instance2 = new SubType();
console.log(instance2.colors);//'red','green','blue'
- 问题:
- 不同子类实例会共享同一个引用类型数据,所以如果有一个修改了它,其他实例访问到的也是修改之后的。
- 创建子类实例的时候不能向构造参数传递参数。
组合继承:构造函数+原型继承
function SuperType(){
this.property =true;
this.colors = ['red','green'];
}
SuperType.prototype.getSuperValue = function(){
return this.property;
}
var parent = new SuperType();
function SubType(arg){
SuperType.call(this,arg);
this.property = false;//子类重写父类属性
}
SubType.prototype = new SuperType();
SubType.prototype.getSubType = function(){
return this.property;
}
var instance = new SubType();
console.log(instance.getSuperValue());//false
instance.colors.push('blue');
console.log(instance.colors);//'red','green','blue'
console.log(parent.colors);//'red','green',
var instance2 = new SubType();
console.log(instance2.colors);//'red','green'
- 组合继承,具有了两种集成方式的有点,同时因为借用了父类的构造函数,所以每个子类实例获得了父类的属性。
- 不足之处:每次都会调用两次超类的构造函数。一次是创建子类原型的时候,另一次是在子类构造函数内部。
寄生继承:
- 调用函数创建对象+增强该对象的属性和方法
function createAnother(original){
var clone = object(original);
clone.sayHi = function(){
console.log('hi');
}
return clone;
}
var person = {
name:"sherry",
friends:['lisa']
}
var p = createAnother(person);
最佳实践:寄生组合继承
function inheritPrototype(subType,superType){
var prototype = object(superType.prototype);
prototype.contructor = subType;
subType.prototype = prototype;
}
另一种实现方式:
function extend(Child, Parent) {
var F = function(){};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype;
}
- 只调用一次superType的构造函数
- 原型链也没有改变
参考:《Javascript高级教程》
网友评论