为什么总是搞不清楚js的继承模式?,但是为什么面试官对你的回答不是很满意或者根本没看懂,我个人觉得应该是缺少一个自己的答题思路。2.答题技巧首先,按照从最低继承模式到最好继承模式的顺序说一下几种继承模式。第二,说说现在的继承模式,与之前的继承模式相比,解决问题的优缺点。问题出在哪里,代码最关键的部分在哪里?下面重点介绍几种常见的继承模式。2.原型链继承代码示例('DBCDouble')console.log(s1)结果打印键:将子类的原型指向父类的实例继承父类的私有属性和原型属性的优点:原型属性和方法被添加到可以简单轻松地访问父类和子类实例。缺点:无法实现多重继承(一个子类继承多个父类)创建子类创建实例时,无法向父类构造函数传递参数。有一个问题是子类实例共享父类的引用属性(因为子类的原型指向父类的一个实例,如果父类的私有属性之一是数组(引用类型),那么任何子类都可以操作这个数组,这会导致其他子类使用的数组发生变化)四、借用父类构造函数继承代码示例functionParent(sex){this.sex=sex}Parent.prototype.setSex=function(){}functionSon(name,age,sex){Parent.call(this,sex)this.name=namethis.age=age}vars1=newSon('DBCdouble',25,'Male')console.log(s1)结果打印Key:在子类构造函数中使用call或apply调用父类构造函数,实现父类私有属性继承(函数复用)优点:创建子类实例时,可以传递给父类参数,可以实现多个继承(在子类构造函数中调用多个父类构造函数ctors)解决了子类实例在原型链继承中共享父类引用属性的问题(即使父类构造函数中有引用类型,在创建子类实例时,会再次调用父类构造函数重新创建这个引用类型数据,引用类型空间会被重新申请)缺点:每次创建子类实例,都必须调用一次父类构造函数,影响性能,只能继承类的父实例属性(私有属性),不继承父类的原型属性5.组合继承(原型链继承+借用构造函数继承)代码示例functionParent(sex){this.sex=sex}Parent.prototype.setSex=function(){}functionSon(name,age,sex){Parent.call(this,sex)this.name=namethis.age=age}Son.prototype=Object.create(Parent.prototype)SonSon.prototype.constructor=Sonvars1=newSon('DBCdouble',25,'male')console.log(s1)打印结果键:通过调用父类构造函数,继承父类的属性并保留传参的优点,通过Object.create(Parent.prototype)创建一个继承父类原型属性的对象,并将这个对象赋值给子类的原型。这样既可以保证父类的构造函数不需要执行两次,又可以让子类继承父类的原型方法优点:创建子类实例时,可以将参数传递给父类实现多重继承(在子类构造函数中调用多个父类构造函数)解决了原型链继承中子类实例共享父类引用属性的问题(即使父类构造函数中存在引用类型。创建子类时instance,会再次调用父类构造函数创建引用类型数据的副本,重新申请引用类型的空间。)父类构造函数只需要执行一次。6.ES6ES6中引入了class关键字,用于类的继承。一个类可以通过extends关键字来继承,类的静态方法也可以通过static关键字来定义。这比ES5通过修改原型链继承更清晰方便。注意:ES5继承的本质是先创建子类的实例对象this,然后将父类的方法添加到this中(Parent.apply(this))。ES6的继承机制完全不同。本质就是将父类实例对象的属性和方法添加到this中(所以必须先调用super方法),然后用子类的构造函数修改this。代码示例classA{constructor(sex){this.sex=sex}showSex(){console.log('这是父类的方法')}}classBextendsA{constructor(name,age,sex){super(sex);this.name=name;this.age=age;}showSex(){console.log('这是子类的方法')}}constb=newB('DBCDOUBLE',25,'Male')console.log(二);打印结果关键:使用extends关键字继承父类的原型属性,调用super继承父类的实例属性,保留了传递参数给父类构造函数的优点。优点:简单易用,无需自己修改原型Chain完成继承我们把代码从ES6编译到ES5,看看类继承代码最终会编译成什么,如下:从上图分析:上面代码示例中的super是指父类构造函数子类继承父类的实例属性,最终通过call或apply实现继承。通过调用extends方法修改子类与父类之间的原型链关系。再看看编译出来的extends方法,如下1.注意Object。setPrototypeOf()方法将指定对象的原型(即内部[[Prototype]]属性)设置为另一个对象或设置为null。2、(.prototype=b.prototype,new())表达式的执行顺序是先执行前者,再返回后者。从上图中,我们可以看出extends做了如下事情:定义了一个function__(){}函数,并将该函数的构造函数指向子类。接下来,将function__(){}函数的原型指向父类的原型。最后将function(){}函数的实例赋值给子类函数。这样子类的实例就可以沿着proto.proto获取到父类的prototype属性。这种继承模式就是俗称的圣杯模式。
