日期:2014-05-16  浏览次数:20377 次

js组合继承+寄生组合继承的实现

原型链继承的方式

function Box() { //Box 构造
this.name = 'Lee';
}
function Desk() { //Desk 构造
this.age = 100;
}
Desk.prototype = new Box(); //Desc 继承了 Box , 通过原型 , 形成链条
var desk = new Desk();
alert(desk.age);
alert(desk.name); // 得到被继承的属性
function Table() { //Table 构造
this.level = 'AAAAA';
}
Table.prototype = new Desk(); // 继续原型链继承
var table = new Table();
alert(table.name); // 继承了 Box 和 Desk

?

在 JavaScript 里,被继承的函数称为超类型 ( 父类,基类也行,其他语言叫法 ) ,继承的函数称为子类型 ( 子类,派生类 ) 。继承也有问题,比如字面量重写原型会中断关系 , 使用引用类型的原型,并且子类型还无法给超类型传递参数。

了解决引用共享和超类型无法传参的问题我们采用一种叫借用构造函数的技术 , 或者成为对象冒充 ( 伪造对象、经典继承 ) 的技术来解决这两种问题。

?

function Box(age) {
this.name = ['Lee', 'Jack', 'Hello']
this.age = age;
}
function Desk(age) {
Box.call(this, age); // 对象冒充,给超类型传参
}
var desk = new Desk(200);
alert(desk.age);
alert(desk.name);
desk.name.push('AAA'); // 添加的新数据,只给 desk
alert(desk.name);


借用构造函数虽然解决了刚才两种问题 , 但没有原型 , 复用则无从谈起 。 所以 , 我们需要 原型链 +借用构造函数 的模式,这种模式成为 组合继承 。
function Box(age) {
this.name = ['Lee', 'Jack', 'Hello']
this.age = age;
}
Box.prototype.run = function () {
return this.name + this.age;
};
function Desk(age) {
Box.call(this, age); // 对象冒充
}
Desk.prototype = new Box(); // 原型链继承
var desk = new Desk(100);
alert(desk.run());

?

?

组合式继承是 JavaScript 最常用的继承模式 ; 但 , 组合式继承也有一点小问题 , 就是超类型在使用过程中会被调用两次 : 一次是创建子类型的时候 , 另一次是在子类型构造函数的内部。

?

寄生组合继承 ,解决了两次调用的问题。
function obj(o) {
function F() {}
F.prototype = o;

return new F();
}
function create(box, desk) {
var f = obj(box.prototype);
f.constructor = desk;
desk.prototype = f;
}
function Box(name) {
this.name = name;
this.arr = [' 哥哥 ',' 妹妹 ',' 父母 '];
}
Box.prototype.run = function () {
return this.name;
};
function Desk(name, age) {
Box.call(this, name);
this.age = age;
}
inPrototype( Box , Desk ); // 通过这里实现继承
var desk = new Desk('Lee',100);
desk.arr.push(' 姐姐 ');
alert(desk.arr);
alert(desk.run()); // 只共享了方法
var desk2 = new Desk('Jack', 200);
alert(desk2.arr); // 引用问题解决

?