conan1992 / blog

记录下知识点..
3 stars 0 forks source link

JS继承的几种方法 #35

Open conan1992 opened 4 years ago

conan1992 commented 4 years ago

原型链继承

其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。

function SuperType(){ 
    this.property = "super"; 
}
SuperType.prototype.getSuperValue = function(){ 
    return this.property; 
}; 
function SubType(){ 
    this.subproperty = "sub"; 
} 
//继承了 SuperType 
SubType.prototype = new SuperType(); 
SubType.prototype.getSubValue = function (){ 
    return this.subproperty; 
}; 
var instance = new SubType(); 
console.log(instance.getSuperValue()); //"super"

缺点

借用构造函数

function SuperType(){ 
    this.colors = ["red", "blue", "green"]; 
} 
function SubType(){ 
    //继承了 SuperType 
    SuperType.call(this); 
} 
var instance1 = new SubType(); 
instance1.colors.push("black"); 
console.log(instance1.colors); //"red,blue,green,black" 
var instance2 = new SubType(); 
console.log(instance2.colors); //"red,blue,gree

优点

console.log(instance1.name); //"布加拉提"

缺点

- 方法都在构造函数中定义,因此函数复用就无从谈起

### 组合继承
```js
function SuperType(name){ 
    this.name = name; 
    this.colors = ["red", "blue", "green"]; 
} 
SuperType.prototype.sayName = function(){ 
    console.log(this.name); 
}; 
function SubType(name, age){ 
    //继承属性
    SuperType.call(this, name); 

    this.age = age; 
} 
//继承方法
SubType.prototype = new SuperType(); 
SubType.prototype.constructor = SubType; 
SubType.prototype.sayAge = function(){ 
    console.log(this.age); 
}; 
var instance1 = new SubType("Nicholas", 29); 
instance1.colors.push("black"); 
console.log(instance1.colors); //"red,blue,green,black" 
instance1.sayName(); //"Nicholas"; 
instance1.sayAge(); //29 
var instance2 = new SubType("Greg", 27); 
console.log(instance2.colors); //"red,blue,green" 
instance2.sayName(); //"Greg"; 
instance2.sayAge(); //27

优点

原型式继承

function object(o){ 
 function F(){} 
 F.prototype = o; 
 return new F(); 
}
//Object.create()

寄生式继承

在原型式继承的基础上,添加方法,使用寄生式继承来为对象添加函数,会由于不能做到函数复用而降低效率;这一点与构造函数模式类似。

function createAnother(original){ 
 var clone = object(original); //通过调用函数创建一个新对象
 clone.sayHi = function(){ //以某种方式来增强这个对象
 alert("hi"); 
 }; 
 return clone; //返回这个对象
} 

寄生组合模式

组合模式是最常用的继承方式,但缺点是都调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部:

function SuperType(name){ 
 this.name = name; 
 this.colors = ["red", "blue", "green"]; 
} 
SuperType.prototype.sayName = function(){ 
 alert(this.name); 
}; 
function SubType(name, age){ 
 SuperType.call(this, name); //第二次调用 SuperType() 

 this.age = age; 
} 
SubType.prototype = new SuperType(); //第一次调用 SuperType() 
SubType.prototype.constructor = SubType; 
SubType.prototype.sayAge = function(){ 
 alert(this.age); 
};

那么怎么优化呢? 我们用寄生式继承来继承超类型的原型:

function inheritPrototype(subType, superType){ 
 var prototype = object(superType.prototype); //创建对象
 prototype.constructor = subType; //增强对象
 subType.prototype = prototype; //指定对象
}
function SuperType(name){ 
 this.name = name; 
 this.colors = ["red", "blue", "green"]; 
} 
SuperType.prototype.sayName = function(){ 
 alert(this.name); 
}; 
function SubType(name, age){ 
 SuperType.call(this, name); 

 this.age = age; 
} 
inheritPrototype(SubType, SuperType); 
SubType.prototype.sayAge = function(){ 
 alert(this.age); 
};