标签:
对于继承的实际运用还没有很好的理解,这里就先说说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
http://www.cnblogs.com/snandy/archive/2013/05/24/3086663.html
标签:
原文地址:http://www.cnblogs.com/coiorz/p/4740269.html