在实际开发中,我们常常会使用类的继承:子类既能继承父类的成员,又能重写和扩展父类的成员。而JavaScript是一种弱类型的直译式脚本语言,它没有类的概念,它的对象也是无法直接进行继承的。
但是我们知道在JavaScript中可以使用function和prototype来模拟类的实现,所以我们也可以用它们来实现基本的单链继承:
// 定义单链继承构造器
(function (window, undefined) {
// 判断单链继承构造器是否已经定义
if (typeof (window.inherit) == "function") {
return;
}
/**
* parentClass:父类function
* subClass:子类function
* subMembers:子类需要重写和扩展父类成员的对象
*/
window.inherit = function (parentClass, subClass, subMembers) {
// 原型链prototype继承
var fun = function () { };
fun.prototype = parentClass.prototype;
subClass.prototype = new fun();
subClass.prototype.constructor = subClass;
subClass.prototype.parentObject = parentClass.prototype;
if (parentClass.prototype.constructor == Object.prototype.constructor) {
parentClass.prototype.constructor = parentClass;
}
// 子类重写和扩展父类成员
if (subMembers) {
for (var key in subMembers) {
var value = subMembers[key];
if (typeof (value) != "undefined") {
subClass.prototype[key] = subMembers[key];
}
}
}
};
})(window);
通过上述方法实现单链继承时,我们还需要在定义的子类function中使用JavaScript中的apply或call方法来显式地调用父类的function,从而达到回调父类构造函数的作用。
下面我们通过定义父类ParentClass和子类SubClass并调用inherit方法对上述原型链法单链继承进行验证:
// 定义父类ParentClass的function
var ParentClass = function () { };
// 通过prototype定义ParentClass的成员对象
ParentClass.prototype.a = function () {
alert("ParentClass.a");
};
ParentClass.prototype.b = function () {
alert("ParentClass.b");
};
// 定义子类SubClass的function
var SubClass = function () {
// 显式调用父类ParentClass的function
ParentClass.apply(this, arguments);
};
// 定义子类需要重写和扩展父类的成员对象
var subMembers = {
// 重写父类ParentClass.b方法
b: function () {
alert("SubClass.b");
},
// 扩展子类SubClass.c方法
c: function () {
alert("SubClass.c");
}
};
// 构造单链继承,将SubClass继承于ParentClass
inherit(ParentClass, SubClass, subMembers);
// 创建子类对象
var subClass = new SubClass();
// 验证继承结果
subClass.a(); // 结果:ParentClass.a
subClass.b(); // 结果:SubClass.b
subClass.c(); // 结果:SubClass.c