继承
知识点:
常见的四种继承方式,
各个继承的优缺点
继承面试考点。
js中的继承,主要是依靠原型链来实现的,原型链是继承的主要工具和方法。
继承的四种方式
原型继承
组合 继承
寄生组合继承
es6的extend继承
1、原型继承
原型继承额核心是把父类的实例作为子类的原型
特点:
父类的实例可以作为子类的实例
父类原有和新增的方法和属性,子类都能访问到
简单容易实现
缺点:
创建的子类实例不能传参
子类实例共享了父类构造函数的引用属性
var person = {
friends : ["Van","Louis","Nick"];
};
var p1 = Object.create(person);
p1.friends.push("Rob");
var p2 = Object.create(person);
p2.friends.push("Style");
console.log(person.friends); //"Van,Louis,Nick,Rob,Style"
2、组合继承
通过调用父类构造函数,继承父类的属性并保存传参的优点;然后通过将父类实例作为子类原型,实现函数复用。
特点:
- 可以继承实例属性和方法,也可以继承原型的属性和方法
- 函数的实例即是子类的实例,也是父类的实例
- 不存在引用属性共享问题。即子类的改变不会影响父类引用类型的共享
- 子类的实例可以传递参数
5.所有子类可以复用父类的方法
//父类
function Father(name){
this.name = name;
this.colors = ['red','blue','green'];
}
//方法定义在原型对象上(共享)
Father.prototype.sayName = function (){
alert(this.name);
};
function Son (name,age){
Father.call(this,name);//核心:继承实例属性,第一次调用father()
this.age = age;
}
//子类和父类共享的方法(实现了父类属性和方法的复用)
son.prototype = new Father ();//核心:继承实例属性,第二次调用Father()
son.prototype.constructor = son;//修复子类的constructor的指向
//优点一:可传参
var instance1 = new Son ('liuis',5);
var instance2 = new son ('zhai',10);
//优点二:共享父类方法
instance1.sayName();//liuis
Instance.sayName();//zhai
//优点三:不共享父类引用属性
instance1.colors.push('black);
console.log(instance1.colors);//"red,blue,green,black"
console.log(instance2.colors);//"red,blue,green"
}
3、寄生组合继承
寄生组合是结合了组合继承和原型继承两者的优点,而且没有缺点
通过寄生的方式,砍掉父类的实例属性,在再次调用父类的构造函数的时候,不会初始化两次实例方法和属性。避免组合继承的除了实现起来比较复杂之外都挺好的。
// 父类 function Father(name){
this.name = name;
this.colors = ["red","blue","green"];
}
// 方法定义在原型对象上(共享)
Father.prototype.sayName = function(){
alert(this.name);
};
function Son(name,age){
Father.call(this,name); // 核心
this.age = age;
}
Son.prototype = Object.create(Father.prototype); // 核心:
Son.prototype.constructor = Son; // 修复子类的 constructor 的指向
4、es6的extend继承
es6的extend继承其实就是寄生组合继承的语法糖
使用extends关键字扩展一个类并继承他的行为。
核心思想:
extends:内部相当于设置了Son.prototype = object.create(Father.prototype);
super():内部相当于调用了Father.call(this);
特点:
子类只要继承父类,可以不写constructor ,一旦写了 ,则在constructor中的第一句话必须是super
把父类当做普通方法的时候,给方法传递参数,让方法中的this是子类的实例
class Son extends Father { // Son.prototype.__proto__ = Father.prototype
constructor(y) {
super(200); // super(200) => Father.call(this,200)
this.y = y
}
}
extends继承详解
这篇文章讲的就很详细。大家可以看一下