史上最为详细的javascript继承(推荐)

场景优点

缺点

继承方式

原型链继承

借用构造函数模式继承

组合继承

原型式继承

寄生式继承

寄生组合

原型链继承
相信小伙伴们都知道到原型链继承(ECMAScript 中描述了原型链的概念,并将原型链作为实现继承的主要方法),因为原型链继承非常的强大,但是也有它的缺点,接下来咱们就按照上面的维度看看原型链继承到底是什么鬼
代码实现:(需要两个构造函数来完成一个原型链继承)

// SuperType 构造函数称为超类 function SuperType (){ this.name='super'; this.friend=[]; this.property = true; } SuperType.prototype.getName=function(){ return this.name; } SuperType.prototype.getSuperValue = function(){ return this.property; }; // SubType 构造函数称为子类 function SubType(name,age){ this.name=name; this.age=age; this.subproperty = false; } SubType.prototype=new SuperType(); SubType.prototype.constrcutor=SubType; SubType.prototype.getAge=function(){ return this.age; } SubType.prototype.getSubValue = function (){ return this.subproperty; }; var child = new SubType('shiny',12); console.log(child.getName)//shiny console.log(child.getAge())//12

图解部分 属性

史上最为详细的javascript继承(推荐)

基本原理

使用类似作用域的原型链,进行继承查找

语言实现

定义两个构造函数,分别为父类(SuperType)、子类(SubType),为了实现子类能够使用父类的属性(本身和原型上面的属性)。重写子类的原型,让子类的原型指向父类实例,这样子类的构造函数就是父类的实例地址,实现子类可以使用父类的本身和原型上的属性

优点

子类可以通过原型链的查找,实现父类的属性公用与子类的实例

缺点  

一些引用数据操作的时候会出问题,两个实例会公用继承实例的引用数据类

谨慎定义方法,以免定义方法也继承对象原型的方法重名

无法直接给父级构造函数使用参数

借用构造函数模式继承
虽然原型链继承很强大但是也有他的缺点,借用构造函数继承可以解决原型链继承的缺点,开线面的解释
代码实现:

// 把父类当中一个函数使用 function SuperType(name){ this.name=name this.friend=['a','b'] } SuperType.prototype.getFriend=function(){ return this.firend } function SubType(name){ // 执行父类函数 SuperType.call(this,name); } var child = new SubType('shiny') var childRed = new SubType('red') console.log(child.name)//shiny console.log(childRed.name)//red child.firend.push('c') console.log(child.friend)//a,b,c console.log(childRed.friend)//a,b console.log(childRed.getFriend)//undefined

基本原理

使用call apply方法,通过执行方法修改tihs (上下文),是的父级的this变成子类实例的this,这样每个实例都会得到父类的属性,实现引用属性备份

使用场景

父类中需要一些子类使用共享的引用类型,并且子类可能会操作父类共享的引用类型
但是父类的非this绑定的属性和方法是不可以使用的(放在父类prototype的属性和方法)

语言实现

不要把父类当中构造函数,当中一个函数来处理这样更容易理解,在子类的构造函数中借用父类函数通过修改this来执行,这样子类的实例包含父类的属性

优点

解决了原型链继承的 引用类型操作问题

解决了父类传递参数问题

缺点

仅仅使用借用构造函数模式继承,无法摆脱够着函数。方法在构造函数中定义复用不可谈

对于超类的原型定义的方法对于子类是不可使用的,子类的实例只是得到了父类的this绑定的属性

考虑到这些缺点,单独使用借用构造函数也是很少使用的

组合继承

上面的两种继承方式(原型链继承+借用构造函数继承),都有自己优缺点,但是他们不是很完美,下面解释一下组合继承

代码实现:

function SuperType(name){ this.name=name; this.firend=['a','b'] } SuperType.prototype.getName=function(){ return this.name } function SubType(name,age){ this.age=age; SuperType.call(this,name) } SubType.prototype=new SuperType(); SubType.prototype.constrcutor = SubType; SubType.prototype.getAge=function(){ return this.age } var childShiny=new SubType('shiny',23); var childRed = new SubType('red',22); childShiny.firend.push('c'); childRed.firend.push('d'); console.log(childShiny.getName()); console.log(childShiny.getAge()); console.log(childRed.getName()); console.log(childRed.getAge()); console.log(childRed.friend);//[a,b,d] console.log(childShiny.friend);//[a,b,c]

 基本原理

使用原型链的继承实现,通过原型查找功能来满足原型链共享方法
使用借用构造函数方法,使用实例备份父类共享引用类型备份

使用场景

得到原型链继承和构造函数继承的优点,是被开发人员认可的一种继承方式,但是也有他的缺点
语言实现

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/3eff3a31242aad5a8364bfe4a0337774.html