ES5 有 6 种方式可以实现继承,分别为
父类的实例作为子类的原型
原型链继承的基本思想是:
利用原型让一个引用类型继承另一个引用类型的属性和方法。
//原型链继承 function Fu() { this.name = "张三"; this.age = 2; } Fu.prototype.child = function() { return this.name; }; let a = new Fu(); console.log(a.child());//张三优点:
简单易于实现,父类的新增的实例与属性子类都能访问缺点:
可以在子类中增加实例属性,如果要新增加原型属性和方法需要在new 父类构造函数的后面无法实现多继承创建子类实例时,不能向父类构造函数中传参数复制父类的实例属性给子类
借用构造函数的技术,基本思想为:
在子类型的构造函数中调用超类型构造函数。
//构造函数继承 function Fu(name){ this.name = name; } function Student(name){ Fu.call(this,name); } let a = new Student("海绵宝宝"); console.log(a.name);//海绵宝宝优点:
可以向超类型的构造函数传递参数解决了原型中包含 引用类型值被所有实例共享的问题缺点:
方法都在构造函数中定义,无法复用不能继承原型属性/方法,只能继承父类的实例属性和方法原型继承的基本思想是:
借用原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。
// 原型式继承 var person = { name:"大头儿子", age:2 } var person1 = Object.create(person); person1.name = "小头爸爸"; person1.age = 26; var person2 = Object.create(person); person2.name = "围裙妈妈"; person2.age = 23; console.log(person1);// {name: "小头爸爸", age: 26} console.log(person2);// {name: "围裙妈妈", age: 23}优点:
不限制调用方法,简单,易实现缺点:
不能多次继承( 组合继承指的是将原型链和借用构造函数技术组合到一块,从而发挥二者之长的一种继承模式。)
调用父类构造函数,继承父类的属性,通过将父类实例作为子类原型,实现函数复用
基本思路:
使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对每个实例属性的继承,既通过了在原型上定义方法来实现了函数复用,有保证了每个实例都有自己的属性。
//组合继承(原型链和借用构造函数) function Fu(name){ this.name = name; } Fu.prototype.sayHi = function (){ console.log(this.name) } function Student(name){ Fu.call(this,name) } let a = new Student("派大星"); console.log(a.name);//派大星( 寄生式继承是与原型式继承紧密相关的一种思路。 )
寄生式继承的思路与寄生构造函数和工厂模式类似:
即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后再像真的是它做了搜有的工作一样返回对象。
// 寄生式继承 function createAnother(original){ var clone = Object(original); clone.sayHi = function (){ console.log("hi"); }; return clone; } var person = { name:'张三', age:2 } var person2 = createAnother(person); person2.sayHi();//hi缺点:
使用寄生继承来为对象添加函数,会由于不能做到函数复用而效率低下。同原型链实现继承一样,包含引用类型值的属性会被所有实例共享通过寄生的方式来修复组合是继承的不足,完美的实现继承
所谓寄生组合式继承,即通过构造函数来继承属性,通过原型链的混成形式来继承方法。
基本思路:
不必为了指定子类型的原理而调用超类型的构造函数,我们需要的仅仅是超类型原型的一个副本,本质上就是使用寄生式继承来继承超类型的原型,然后,再将结果指定给子类型的原型。
// 寄生组合式继承(构造函数和原型的结合)最理想的继承方案 function inheritPrototype(subType,superType){ var prototype = Object(superType.prototype);//创建对象 prototype.constructor = subType;//增强对象 subType.prototype = prototype;//指定对象 } function SuperType(name){ this.name = name; } SuperType.prototype.sayHi = function (){ console.log(this.name); } function SuberType(name){ SuperType.call(this,name); } inheritPrototype(SuberType,SuperType); var a = new SuperType("张三"); a.sayHi();//张三优点:
只调用了一次超类构造函数,效率更高优点:
代码量少,易懂ES5继承和ES6继承的区别:
es5继承首先是在子类中创建自己的this指向,最后将方法添加到this中 Child.prototype=new Parent() || Parent.apply(this) || Parent.call(this) es6继承是使用关键字先创建父类的实例对象this,最后在子类class中修改this