原型链继承
function Person(){
this.name = "hello",
this.hobby = ['唱歌','踢球'];
}
function Child(){
}
//关键代码
Child.prototype = new Person();
Child.prototype.constructor = Child;
var child = new Child();
child.hobby .push('跑步');
var child2 = new Child();
console.log(child2.hobby ) //['唱歌','踢球','跑步']
总结:缺点不能传递参数,2,如果父类的属性是引用类型,子类实列修改了该属性,其他的子类实列会会共享该属性。
借用用构造函数
借用构造函数实现继承,也就是通过call或者apply方法调用父类构造函数,以实现继承。
//父类
function Person(name){
this.name = name;
this.hobby = ['唱歌','踢球','跑步']
}
Person.prototype.eat = function(){
console.log("好吃");
}
//子类
function Child(age,name){
this.age = age;
Person.call(this,name)
}
//实列
var child1 = new Child('11','wucr');
child1.push('学习')
console.log(child1.hobby )// ['唱歌','踢球','跑步','学习']
var child2 = new Child('11','wucr');
console.log(child2.hobby )// ['唱歌','踢球','跑步']
借用构造函数有缺点总结:
缺点:1,子类无法继承父类在原型链上的属性和方法。2,每个实例都拷贝一份,占用内存大,尤其是方法过多的时候。(函数复用又无从谈起了,本来我们用 prototype 就是解决复用问题的)
优点:解决了通过原型链继承子类对于父类引用类型属性的修改,导致其他子类实列共享了修改的问题
组合继承
组合继承(原型链继承+借用构造函数继承)由于这两种继承方式都存在各自的优缺点,从而将他们优点结合起来,通过原型继承父类原型上的属性和方法,通过构造函数的方法继承父类的属性
function Person(name){
this.name = name;
this.hobby = ['唱歌','踢球','跑步']
}
Person.prototype.eat = function(){
console.log("好吃");
}
//子类
function Child(age,name){
this.age = age;
Person.call(this,name) //借用构造函数
}
Child.prototype = new Person(); // 原型链
Child.prototype.constructor = Child;
缺点:组合继承是js最常用的继承模式,组合继承最大的问题就是无论在什么情况下,都会调用两次构造函数:一次是在创建子类型原型时,另一次是在子类构造函数内部。
寄生组合继承
寄生组合继承就是避免两次调用父类构造函数,通过赋值直接继承父类的原型
function Person(name){
this.name = name;
this.hobby = ['唱歌','踢球','跑步']
}
Person.prototype.eat = function(){
console.log("好吃");
}
//子类
function Child(age,name){
this.age = age;
Person.call(this,name) //借用构造函数
}
var proObj = Object.create(Person.prototype);
proObj.constructor = Child;
Child.prototype = proObj;