js中的继承
继承: 让子类构造函数拥有父类构造函数上的实例属性和原型属性。子类实例拥有父类实例上的属性和方法
以下是继承的几种方法
原型链继承: 让子类构造函数的原型对象是父类构造函数的实例
function Animal(type){
this.type=type;
}
function Cat(name){
this.name=name;
}
Cat.prototype= newAnimal("cat")
let cat1=new Cat(" Tom")
缺点: 1. 子类实例无法单独设置父类实例属性接受的参数;2. 子类实例共享父类的实例属性
经典继承又称构造函数继承:使用call方法来实现对父类构造函数的继承,原型直接指向父类原型来实现原型继承
function Animal(type){
this.type = type;
this.friend = [ ];
}
Animal.prototype.hobby = ["run"];
function Cat(name, type){
Animal.call(this, type); 解释:调用call方法 使Animal中的this指向更改为Cat中的this指向
this.name = name;
}
缺点:这样复制会导致子类原型的更改反映在父类原型上,不具备父类构造函数原型上的方法
组合继承:利用构造函数继承和原型链继承
function Animal(type){
this.type = type;
this.friend = [ ];
}
Animal.prototype.hobby = ["run"];
function Cat(name, type){
Animal.call(this, type); 组合1
this.name = name;
}
Cat.prototype=new Animal() 组合2
寄生式组合继承
解决缺点的方法:
1,
function Animal(type){
this.type = type;
this.friend = [ ];
}
Animal.prototype.hobby = ["run"];
function Cat(name, type){
Animal.call(this, type); 组合1
this.name = name;
}
组合2
function Temp(){} 声明一个空构造函数 让空函数的原型对象为父类构造函数的原型对象
temp.prototype=Animal.prototype;
Cat.prototype=new Temp() 这样就过滤掉了重复的实例属性
2,
当下最流行的解决方法 ,组合继承: 借用构造函数继承+原型链继承
组合2
Cat.prototype = {
constructor: Cat, 会丢失这个属性 所以要加上 重新值回原本的实例对象
__proto__: Animal.prototype
}
缺点:这样指定会失去原型的动态性
3,
2的方法也就很完美了 3,为了解决我方法中的缺点
解决方法:直接指定
Cat.prototype.__proto__=Animal.prototype;
缺点:这样又会丢失constructor原型
在实际中还是2方法比较多用
浙公网安备 33010602011771号