原型链
function SuperType(){ this.property="SuperType_true"; } SuperType.prototype.getSuperValue=function(){ return this.property; }; function SubType(){ this.subproperty="SubType_false"; } SubType.prototype=new SuperType(); SubType.prototype.getSubValue=function(){ return this.subproperty; }; var instance=new SubType(); alert(instance.getSuperValue()); //SuperType_true
使用原型链进行继承,对象继承的东西都是共享的。此时,使用对象修改继承的属性,即是直接修改父类原型里的属性,则其他对象的这个属性也会发生改变。
除非有特殊情况,不然原型链只可用于实现方法继承。
另外,现在instance.constructor 指向SuperType,因为instance的原型是SuperType的实例。
借用构造函数(也叫伪造对象或经典继承)
function SuperType(name){ this.name=name; } function SubType(name,age){ SuperType.call(this,name); this.age=age; } var instance1=new SubType("Lufy",18); var instance2=new SubType("Natro",16);
使用借用构造函数方法继承得来的东西,对象间不共享。这样的话就没有函数复用,造成资源浪费。
借用构造函数可用于继承父类属性,并且很少单独使用。
组合继承
function SuperType(name){ this.name=name; this.colors=["red","blue","green"] } SuperType.prototype.sayName=function(){ alert(this.name); }; function SubType(name,age){ SuperType.call(this,name); this.age=age; } SubType.prototype=new SuperType(); SubType.prototype.sayAge=function(){ alert(this.age); } var instance1=new SubType("Lufy",22); instance1.colors.push("black"); var instance2=new SubType("Naruto",20);
组合使用原型链和借用构造函数实现继承。使属性在子类实例中;方法则需要沿着原型链查到父类原型,实现了函数复用。
原型式继承
var person={ name:"Nicholas", friends:["Shelby","Court","Van"] }; var anotherPerson=Object.create(person); anotherPerson.name="Greg"; anotherPerson.friends.push("Rob"); var yetAnotherPerson=Object.create(person,{ name:{ value:"Linda" } }); yetAnotherPerson.friends.push("BarBie"); console.info(anotherPerson.friends); //["Shelby", "Court", "Van", "Rob", "BarBie"]
其中,Object.create就是规范化的这个函数:
function object(o){ function F(){}; F.prototype=o; return f(); }
只想让一个对象和另一个对象类似,可以使用 原型式继承。
寄生式继承
var person={ name:"Jack", age:20 }; var anotherPerson=createAnother(person); anotherPerson.sayName();
寄生组合式继承
组合式继承非常经典,但它也有不足。它的问题就是:不论在什么情况下,都会调用两次超类型构造函数,浪费了性能。
function SuperType(name){ this.name=name; this.colors=["red","blue","green"] } SuperType.prototype.sayName=function(){ alert(this.name); }; function SubType(name,age){ SuperType.call(this,name); //第二次调用SuperType() this.age=age; } SubType.prototype=new SuperType(); //第一次调用SuperType() SubType.prototype.sayAge=function(){ alert(this.age); } var instance1=new SubType("Lufy",22); instance1.colors.push("black"); var instance2=new SubType("Naruto",20);
为了弥补这个缺陷,诞生了 “寄生组合式继承”:
function inheritPrototype(subType,superType){ var prototype=Object(superType.prototype); prototype.constructor=subType; subType.prototype=prototype; } function SuperType(name){ this.name=name; this.colors=["red","blue","green"]; } SuperType.prototype.sayName=function(){ alert(this.name); }; function SubType(name,age){ SuperType.call(this,name); //调用SuperType构造函数 this.age=age; } inheritPrototype(SubType,SuperType); SubType.prototype.sayAge=function(){ alert(this.age); }; var p1=new SubType("Jack",20);
此方法的高效体现于其只调用一次超类构造函数。
开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式。
JavaScript实现继承总结
时间: 2024-10-11 03:47:55