什么是继承
js中,继承是一种允许我们在已有类的基础上创建新类的机制;它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
为什么要有继承
提高代码的重用性、较少代码的冗余
继承的相关实现
想要实现继承,就得有个被继承的父类
目前我总结的一共有6种继承方式
- 原型链继承,
- 借用构造函数继承,
- 组合式继承(原型链+构造函数),
- 原型式继承,
- 寄生式继承,
- 寄生组合式继承
function Person(name){
this.name = name;
this.sum=function(){
alert('',this.name)
}
}
Person.prototype.age = 100
1. 原型链继承
-
实现方式: 利用原型链的特点继承,让实例的原型等于父类的实例
-
优点: 实例可以继承父类的构造个函数,实例的构造函数,父类的原型
-
缺点: 不能向父类传递参数,由于实例的原型等于父类的实例,那么改变父类的属性,实例的属性也会跟着改变
function child(){ this.name="xiaoming" } child.prototype = new Person() let child1 = new Child() child1.name //xiaoming child1.age //100 child1 instanceof Person //true
2. 借用构造函数继承
-
实现方式: 使用call/apply将父类的构造函数引入子类函数
-
优点: 可以祢补原型链继承的缺点,可以向父类传递参数,只继承父类构造函数的属性
-
缺点: 不能复用,每次使用需要重新调用,每个实例都是父类构造函数的副本,比较臃肿
function child(){ Person.call(this,'xiaoming') } let child1 = new child() child1.name //xiaoming child1.age //100 child1 instanceof Person //false
3. 组合式继承
-
实现方式: 复用+可传递参数
-
优点: 基于原型链的优点和借用构造函数的优点
-
缺点: 调用两遍父类函数
function child(){ Person.call(this,'xiaoming') } child.prototype = new Person let child1 = new child() child1.name //xiaoming child1.age //100 child1 instanceof Person //true child instanceof Person //false
4. 原型式继承
-
实现方式: 函数包装对象,返回对象的引用,这个函数就变成可以随时添加实例或者对象,Object.create()就是这个原理
-
优点: 复用一个对象用函数包装
-
缺点: 所有实例都继承在原型上面 无法复用
function child(obj){ function F(){} F.prototype = obj return new F() } let child1 = new Person() let child2 = child(child1) child2.age //100
5. 寄生式继承
-
实现方式: 在原型式继承外面包了一个壳子
-
优点: 创建一个新对象
-
缺点: 没有用到实例 无法复用
function child(obj){ function F(){} F.prototype = obj return new F() } let child1 = new Person() function subObject(){ let sub =child(child1) sub.name='xiaoming' return sub } let child2 = subObject(child1) typeof subObject //function typeof child2 //object child2.age //100
6. 寄生组合式继承
-
实现方式: 在函数内返回对象的调用
-
优点: 函数的实例等于另外的一个实例,使用call/apply引入另一个构造函数,可传递参数,修复了组合继承的问题
-
缺点: 无法复用
function child(obj){ function F(){} F.prototype = obj return new F() } let child1 = child(Person.prototype) function Sub(){ Person.call(this) } Sub.prototype = child child.constructor = Sub let sub1 = new Sub() sub1.age //100