许多OO语言都支持两种继承方式,接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际的方法。由于在ECMAScript中,函数没有签名,无法实现接口继承,只支持实现继承,而且其实现继承主要是通过原型链来实现的。
利用原型让引用类型继承另一个引用类型的属性和方法。
原型、构造函数和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针, 而实例包含一个指向原型对象的内部指针。
假如让原型对象等于另一个类型的实例,结果会如何?显然,此时的原型对象包好一个指向另一个原型的指针,相应地,另一个原型中也包含着指向另一个函数的指针。假如另一个原型又是另一个类型的实例,上述关系依然成立,如此层层递进,构成了实例与原型的链条。这就是所谓原型链的基本概念。
functionSuperType(){this.superPRoperty=true;}SuperType.prototype.getSuperProperty=function(){console.log(this.superProperty);};functionSubType(){this.subProperty=false;}SubType.prototype=newSuperType();SubType.prototype.getSubProperty=function(){console.log(this.subProperty);};varinstance=newSubType();instance.getSuperProperty();//true原型链模式的缺点:通过原型链实现继承时,原型实际上为另一个类型的实例,于是,原先的实例属性也变成了原型属性。而包含引用类型值的原型属性会被所有实例共享。
functionSuperType(){this.superProperty=true;this.colors=["red","blue","green"];}SuperType.prototype.getSuperProperty=function(){console.log(this.superProperty);};functionSubType(){this.subProperty=false;}SubType.prototype=newSuperType();SubType.prototype.getSubProperty=function(){console.log(this.subProperty);};varinstance1=newSubType();instance1.colors.push("purple");console.log(instance1.colors);//["red","blue","green","purple"]varinstance2=newSubType();console.log(instance2.colors);//["red","blue","green","purple"]为了解决原型链模式引用类型属性继承的问题,接下来讨论借用构造函数模式。
借用构造函数模式的缺点:仅是借用构造函数,无法避免构造函数模式存在的问题——方法都在构造函数中定义,函数复用无从谈起。为解决这个问题,接下来讨论组合继承模式。
组合继承:原型链模式+借用构造函数模式,原型链模式实现对原型属性和方法的继承,借用构造函数模式实现对实例属性的继承。
functionSuperType(name){this.name=name;this.colors=["red","blue","green"];}SuperType.prototype.sayName=function(){console.log(this.name);};functionSubType(name,age){SuperType.call(this,name);this.age=age;}SubType.prototype=newSuperType();varinstance1=newSubType("Brittany",23);instance1.colors.push("black");console.log(instance1.colors);//["red","blue","green","black"]console.log(instance1.sayName());//Brittanyvarinstance2=newSubType("Closure",24);console.log(instance2.colors);//["red","blue","green"]console.log(instance2.sayName());//Closureconsole.log(instance1instanceofSubType);//trueconsole.log(instance1instanceofSuperType);//trueconsole.log(SubType.prototype.isPrototypeOf(instance1));//trueconsole.log(SuperType.prototype.isPrototypeOf(instance1));//true时间:2014-10-22
地点:合肥
引用:《Javascript高级程序设计》
新闻热点
疑难解答