本文全面讲述了JS继承分类,原理与用法。分享给大家供大家参考,具体如下:
许多OO语言都支持两种继承方式:接口继承和实现继承。接口继承只继承方法签的名,而实现继承则继承实际的方法。由于ECMAScript中的函数没有签名,所以在JS中无法实现接口继承.ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现的,所以,下面所要说的<强>原型链继承强>,<强>借用构造函数继承强>,<强>组合继承强>,<强>原型式继承强>,<强>寄生式继承强>和<强>寄生组合式继承强>都属于实现继承。
最后的最后,我会解释ES6中的<代码> 代码>扩展语法利用的是寄生组合式继承。
ECMAScript中描述了<强>原型链>强劲的概念,并将原型链作为实现继承的主要方法。其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。实现原型链继承有一种基本模式,其代码大致如下:
函数的超类型(){ 这一点。财产=true; } SuperType.prototype。getSuperValue=https://www.yisu.com/zixun/function () { 返回this.property; }; 函数亚型(){ 这一点。subproperty=false; } 亚型。原型=new超类型();//敲黑板!这是重点:继承了超类型 SubType.prototype。getSubValue=function () { 返回this.subproperty; }; var=new实例亚型(); 警报(instance.getSuperValue ());//正确的 >之前原型链继承的一个本质是重写原型对象,代之以一个新类型的实例;给原型添加方法的代码一定要放在替换原型的语句之后,在通过原型链实现继承时,不能使用对象字面量创建原型方法。
实例属性在实例化后,会挂载在实例对象下面,因此称之为实例属性。上面的代码中<代码>亚型。原型=new超类型();> 代码,执行完这条语句后,原超类型的实例属性就挂载在了<代码>亚型。> 原型代码对象下面。这其实是个隐患,具体原因后面会讲到。
每次去查找属性或方法的时候,在找不到属性或方法的情况下,搜索过程总是要一环一环的前行到原型链末端才会停下来。
所有引用类型默认都继承了对象,而这个继承也是通过原型链实现的。由此可知,所有函数的默认原型都是对象的实例,因此函数的默认原型都会包含一个内部指针,指向对象。原型。
<强>缺点:强>
<李>最主要的问题来自包含引用类型值的原型。在通过原型来实现继承时,原型实际上会变成另一个类型的实例。于是,原先的实例属性也就顺理成章地变成了现在的原型属性了。李> <李>在创建子类型的实例时,不能向超类型的构造函数传递参数。李>
<李>第一种方式是使用操作符,只要用这个操作符来测试实例的原型链中是否出现过某构造函数。如果有,则就会返回正确的;如果无,则就会返回错误的。以下为示例代码:李>
警报(实例实例对象);//正确的 警报(实例instanceof超类型);//正确的 警报(实例instanceof亚型);//正确的 >之前 <李>第二种方式是使用isPrototypeOf()方法。同样,只要是原型链中出现过的原型,都可以说是该原型链所派生出来的实例的原型。以下为示例代码:李>alert (Object.prototype.isPrototypeOf(实例));//正确的 alert (SuperType.prototype.isPrototypeOf(实例));//正确的 alert (SubType.prototype.isPrototypeOf(实例));//正确的 >之前
借用构造函数继承,也叫伪造对象或经典继承。其基本思想相当简单,即在子类型构造函数的内部调用超类型构造函数。其继承代码大致如下:
函数的超类型(){ 这一点。颜色=(“红”、“蓝”、“绿色”); } 函数亚型(){ SuperType.call(这个);//敲黑板!注意了这里继承了超类型 } var instance1=new亚型(); instance1.colors.push(“黑色”); 警报(instance1.colors);//昂臁⒗丁⒙獭⒑凇? var instance2=new亚型(); 警报(instance2.colors);//昂臁⒗丁⒙獭? >之前通过使用<代码>调用()代码>方法(或<代码> apply() 代码>方法也可以),我们实际上是在(未来将要)新创建的子类的实例环境下调用父类构造函数。
15分钟深入了解JS继承分类,原理与用法