您的位置:首页 > Web前端 > JavaScript

JS的继承

2015-08-18 20:25 603 查看
对于继承的实际运用还没有很好的理解,这里就先说说JS中继承的实现。

类式继承

作为基于原型的语言,JS也可以模仿类式继承。首先声明一个父类

function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function() {
console.log("hello");
};


继承就显得复杂一点

function Programmer(name, age, work) {
Person.apply(this, arguments);    //修正父类构造函数的this
this.work = work;
}
Programmer.prototype = new Person();
Programmer.prototype.constructor = Programmer;
Programmer.prototype.program = function() {
console.log("coding");
};

var p = new Programmer("jay", 26, "javascript");
p.sayHello();   //hello
console.log(p.name);    //jay 注意这个不是继承属性,而是p本身的属性哦


把Programmer.prototype指向父类Person的一个实例对象,那么在子类Programmer的实例中访问成员时,如果找不到,就会去这个Person实例对象里找,还没有就到Person.prototype里找,相当于人为的设置了一条原型链来达到继承的效果。

只要不把Programmer.prototype重写,Programmer的所有实例的原型对象共享同一个对象,即Person实例。我们仍然可以通过修改原型来达到修改所有实例的效果。

有时父类的构造函数很庞大,里面有很多复杂的或我们不需要的操作,我们想要避免创建父类的实例,改进的方法是借用一个空的构造函数作为中间量来链接原型链,我们把整个过程包装到一个函数里

function inherit(subClass, superClass) {
var F = function() {};
F.prototype = superClass.prototype;
subClass.prototype = new F();
subClass.prototype.constructor = subClass;
subClass.superproto = superClass.prototype;    //增加一个自定义属性superproto,这样我们可以通过这个属性引用到父类构造函数
}


function Programmer(name, age, work) {
Programmer.superproto.constructor.apply(this, arguments);    //等价于Person.apply(this, arguments),这样就避免了在子类的声明中固化父类构造函数名称
this.work = work;
}
inherit(Programmer, Person);
Programmer.prototype.program = function() {
console.log("coding");
};


注意到,作为一个中间量,我们可以只创建一个F然后重用它,因此inherit可以这样改进一下

var inherit = (function() {
var F = function() {};
return function(subClass, superClass) {
F.prototype = superClass.prototype;
subClass.prototype = new F();
subClass.prototype.constructor = subClass;
subClass.superproto = superClass.prototype;
};
})();


掺元类(Mixin)

这是一种代码重用的方法而不是严格的继承。其做法大体是,先创建一个包含各种公用方法的类,即掺元类,然后用它去扩充其它类。掺元类一般不会实例化也不直接调用,其目的就是扩充其它类,提供自己的方法。

function augment(destClass, srcClass) {
for (method in srcClass.prototype) {
if (!destClass.prototype[method]) {
destClass.prototype[method] = srcClass.prototype[method];
}
}
}


扩充多个掺元类,变相的多继承

function augment(destClass /*, a number of srcClasses */) {
var classes = Array.prototype.splice.call(arguments, 1);
for (var i = 0, len = classes.length; i < len; i++) {
var srcClass = classes[i];
for (method in srcClass.prototype) {
if (!destClass.prototype[method]) {
destClass.prototype[method] = srcClass.prototype[method];
}
}
}
}


参考:http://blog.csdn.net/pigpigpig4587/article/details/25152031

/article/4664465.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: