1.原型链

实现原理 : 重写子类原型对象,代之以一个新类型的实例。
function SuperType(){
    this.property = true;
}
SuperType.prototype.getSuperValue = function(){
    return this.property;
}

function SubType (){
    this.subproperty = false;
}
// 继承了 SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function(){
    return this.subproperty;
}

var instance = new SubType();
alert(instance.getSuperValue()); // true
继承后的实例和构造函数和原型之间的关系图如下:

lianzi.png

缺点

1.包含引用类型值的原型属性会被所有实例共享

function SuperType(){
    this.colors = ['red','blue','green']
}
function SubType(){}
SubType.prototype = new SuperType();

let instance = new SubType();
instance.colors.push('black');
console.log(instance.colors) // red,blue,green,black

let instance2  = new SubType();
console.log(instance2.colors) // red,blue,green,black

2.在创建子类型的实例时,无法向超类型的构造函数中传递参数

2.借用构造函数

实现原理 : 在子类型构造函数的内部调用超类型构造函数。

函数只不过是在特定环境中执行代码的对象,因此通过使用apply()和call()方法也可以在(将来)新创建的对象上执行构造函数,代码如下

function SuperType(){
    this.colors = ['red','blue','green']
}
// 继承SuperType
function SubType(){
    SuperType.call(this)
}

let instance = new SubType();
instance.color.push('black');
console.log(instance.color); // red,blue,green,black

let instance2 = new SubType();
console.log(instance2.color); // red,blue,green

// 避免了引用类型值的原型属性被实例共享的问题
传递参数
function SuperType(name){
    this.name = name;
}

function SubType(){
    //继承SuperType,同时传递参数
    SuperType.call(this,'张三');
    this.age = 22;
}

let instance = new SubType();
console.log(instance.name); // 张三
console.log(instance.age);  // 22
缺点

1.如果仅仅借用构造函数,那么将无法避免构造函数模式存在的问题——方法都在构造函数中定义,函数复用就无法谈起。
2.超类型原型中定义的方法,子类型是不可见的。结果所有类型都只能使用构造函数模式。


smallgang
232 声望7 粉丝