标签:传递 避免 ret tor 二次 重复 做了 return 实现继承
ES5实现继承的方法有6种,有5种都是有缺点的,我们直接说无缺点的最后一种,前面5种有的没有达到下面说的实现准确继承所需实现的部分,可自行百度
实现准确的继承需要做好以下几部分:
一、 属性必须定义为实例属性,即在this上定义属性,这样保证了属性有引用值的时候,不会在多个实例之间共享
二、方法必须定义为原型属性,即定义在构造函数的 protoType 上, 这样保证了方法可以在多个实例之间共享,避免了在每个实例上都创建一遍方法
三、子类构造函数在实例化的时候必须要能够给父类构造函数传递参数,这样才能够使子类实例拥有父类的属性
四、必须避免冗余现象,即无需在实例和原型上重复定义的属性或方法
要达到以上几方面,只有寄生式组合继承能够完全做到,附代码:
// 父类构造函数 function SuperType(name){ // 满足第一条,属性必须为实例属性,即定义在this上 this.name=name; this.colors=[‘red‘,‘blue‘,‘green‘]; } // 满足第二条,方法必须定位在原型上 SuperType.protoType.sayName=function(){ console.log(this.name); } // 子类构造函数 function SubType(name,age){ // 满足第三条,子类的构造函数在实例化的时候能够给父类构造函数传递参数 SuperType.call(name); /* 注意这里的 SuperType.call 必须放在定义实例属性之前,确保了 SuperType 构造函数不会覆盖 SubType 定义的属性 */ this.age=age; } function inheritPrototype(subType,superType){ // 返回的protoType是空构造函数的实例,该实例的原型就是父类的原型 let protoType = object(superType.protoType); protoType.constructor = subType; // 子类构造函数的原型指向了空构造函数返回的实例 subType.protoType = protoType; } /* 该函数做了3件事: 1 创建一个空的构造函数 2 将该函数的原型指向了传进来的对象 3 返回构造函数的实例 */ function object(o){ function F(){}; F.protoType = o; return new F(); }
第四条是通过寄生式组合继承解决了组合继承重复在实例和原型上定义属性。组合继承代码:
function SuperType(name){ this.name=name; this.colors=[‘red‘,‘blue‘,‘green‘]; } SuperType.protoType.sayName=function(){ console.log(this.name); } function SubType(name,age){ // 第一次调用父类构造函数,会在子类实例上定义属性 SuperType.call(name); this.age=age; } // 第二次调用父类构造函数,会在子类原型上定义属性,造成冗余现象 SubType.protoType = new SuperType();
标签:传递 避免 ret tor 二次 重复 做了 return 实现继承
原文地址:https://www.cnblogs.com/starboy13/p/14870308.html