JS 面向对象之继承--多种组合继承
这一次要讲 组合、原型式、寄生式、寄生组合式继承方式。
1. 组合继承:又叫伪经典继承,是指将原型链和借用构造函数技术组合在一块的一种继承方式。
下面来看一个例子:
View Code
1 function SuperType(name) { 2 this.name = name; 3 this.colors = ["red", "blue", "green"]; 4 } 5 SuperType.prototype.sayName = function() { 6 alert(this.name); 7 } 8 function SubType(name, age) { 9 SuperType.call(this, name); 10 this.age = age; 11 } 12 13 //继承方法 14 SubType.prototype = new SuperType(); 15 SubType.prototype.sayAge = function() { 16 alert(this.age); 17 } 18 19 var instance1 = new SubType("Nicholas", 29); 20 instance1.colors.push("black"); 21 alert(instance1.colors); //red,blue,green,black 22 instance1.sayName(); //Nicholas 23 instance1.sayAge(); //29 24 25 var instance2 = new SubType("Greg", 27); 26 alert(instance2.colors); //red,blue,green 27 instance2.sayName(); //Greg 28 instance2.sayAge(); //27
组合继承避免了原型链和借用构造函数的缺陷,融合它们的优点。
2. 原型式继承
可以在不必预先定义构造函数的情况下实现继承,其本质是执行对给定对象的浅复制。而复制得到的副本还可以得到进一步的改造。
View Code
1 function object(o) { 2 function F(){}; 3 F.prototype = o; 4 return new F; 5 } 6 7 var person = { 8 name: "Nicholas", 9 friends: ["Shelby", "Court", "Van"] 10 }; 11 12 var antherPerson = object(person); 13 antherPerson.name = "Greg"; 14 antherPerson.friends.push("Rob"); 15 16 var antherPerson = object(person); 17 antherPerson.name = "Linda"; 18 antherPerson.friends.push("Barbie"); 19 20 alert(person.friends); //Shelby,Court,Van,Rob,Barbie
3. 寄生式继承
与原型式继承非常相似,也是基于某个对象或某些信息创建一个对象,然后增强对象,最后返回对象。为了解决组合继承模式由于多次调用超类型构造函数而导致的低效率问题,可以将这个模式与组合继承一起使用。
View Code
1 function object(o) { 2 function F(){}; 3 F.prototype = o; 4 return new F; 5 } 6 function createAnother(original) { 7 var clone = object(original); 8 clone.sayHi = function() { 9 alert("Hi"); 10 }; 11 return clone; 12 } 13 14 var person = { 15 name: "Nicholas", 16 friends: ["Shelby", "Court", "Van"] 17 }; 18 19 var anotherPerson = createAnother(person); 20 anotherPerson.sayHi();
4. 寄生组合式继承
集寄生式继承和组合继承的优点与一身,是实现基本类型继承的最有效方式。
View Code
1 //继承原型 2 function extend(subType, superType) { 3 function F(){}; 4 F.prototype = superType.prototype; 5 6 var prototype = new F; 7 prototype.constructor = subType; 8 subType.prototype = prototype; 9 } 10 11 //超类方法 12 function SuperType(name) { 13 this.name = name; 14 this.colors = ["red", "blue", "green"]; 15 } 16 SuperType.prototype.sayName = function() { 17 return this.name; 18 } 19 20 //子类方法 21 function SubType(name, age) { 22 SuperType.call(this, name); 23 this.age = age; 24 } 25 26 //继承超类的原型 27 extend(SubType, SuperType); 28 29 //子类方法 30 SubType.prototype.sayAge = function() { 31 return this.age; 32 } 33 34 var instance1 = new SubType("Shelby"); 35 var instance2 = new SubType("Court", 28); 36 37 instance1.colors.push('black'); 38 39 alert(instance1.colors); //red,blue,green,black 40 alert(instance2.colors); //red,blue,green 41 42 alert(instance1 instanceof SubType); //true 43 alert(instance1 instanceof SuperType); //true
这段例子的高效率体现在它只调用了一次SuperType构造函数,并且因此避免了在SubType.prototype上面创建不必要的多余的属性。与此同时,原型链还能保持不变。因此,还能正常使用instanceof 和 isPrototypeOf()。开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式。