组合继承
//组合继承(有时候也较伪经典继承):将原型链和借用构造函数的技术组合到一块 //思路:借用构造函数继承属性、原型链继承方法。避免了借用构造函数的原型方法不可复用,只有构造函数的属性可以复用的弊端 function SuperType(name) { this.name = name; this.colors = ["red", "blue"]; } SuperType.prototype.sayName = function () { alert(this.name); } function SubType(name, age) { //继承了SuperType2同时还传递了参数 SuperType.call(this, name);//第二次调用SuperType() //SuperType2.apply(this, [name]); this.age = age; } SubType.prototype = new SuperType();//第一次调用SuperType() SubType.prototype.sayAge = function () { alert(this.age); } var instance1 = new SubType("Tom", "20"); instance1.colors.push("black"); alert(instance1.colors); instance1.sayName(); instance1.sayAge(); var instance2 = new SubType("Lucy", "25"); alert(instance2.colors); instance2.sayName(); instance2.sayAge();
寄生组合式继承
function object(o) { function F() {} F.prototype = o; return new F(); } 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"]; } SuperType.prototype.sayName = function () { alert(this.name); } function SubType(name, age) { SuperType.call(this, name); this.age = age; } inheritPrototype(SubType, SuperType); SubType.prototype.sayAge = function () { alert(this.age); } var instance1 = new SubType("Tom", "22"); instance1.colors.push("black"); console.dir(instance1); var instance2 = new SubType("Lucy", "25"); console.dir(instance2);
两个的区别主要在红色代码部分
组合继承是直接用的SuperType的实例,实例包含了自身的属性和原型对象
寄生组合式继承用的是SuperType的原型对象的实例,不包含SuperType构造函数的属性
也就是说,组合继承调用了两次SuperType()
寄生组合继承相比组合继承更高效,所以寄生组合继承是引用类型最理想的继承范式