你的位置:首页 > 软件开发 > Java > 详解Javascript的继承实现(二)

详解Javascript的继承实现(二)

发布时间:2016-03-27 16:00:15
上文《详解Javascript的继承实现》介绍了一个通用的继承库,基于该库,可以快速构建带继承关系和静态成员的javascript类,好使用也好理解,额外的好处是,如果所有类都用这种库来构建,还能使代码在整体上保持一致的风格,便于其它同事阅读和理解。在写完该文之后,这两天时不时都 ...

详解Javascript的继承实现(二)

上文《详解Javascript的继承实现》介绍了一个通用的继承库,基于该库,可以快速构建带继承关系和静态成员的javascript类,好使用也好理解,额外的好处是,如果所有类都用这种库来构建,还能使代码在整体上保持一致的风格,便于其它同事阅读和理解。在写完该文之后,这两天时不时都在思考这个库可能存在的问题,加上这两天又在温习《JavaScript面向对象编程指南》这本书继承这一章的内容,发现对继承的内容有了一些新的发现和理解,有必要再把这两天的收获再分享出来。

1. 继承库的注意事项

为了方便阅读本部分的内容,只好先把上文继承库的实现代码和演示代码再搬出来,省的还得回到那篇文章去找相关内容,好在代码我加了折叠的功能,即使不想展开看,也不会太影响阅读:

//继承库实现部分var Class = (function () {  var hasOwn = Object.prototype.hasOwnProperty;  //用来判断是否为Object的实例  function isObject(o) {    return typeof (o) === 'object';  }  //用来判断是否为Function的实例  function isFunction(f) {    return typeof (f) === 'function';  }  //简单复制  function copy(source) {    var target = {};    for (var i in source) {      if (hasOwn.call(source, i)) {        target[i] = source[i];      }    }    return target;  }  function ClassBuilder(options) {    if (!isObject(options)) {      throw new Error('Class options must be an valid object instance!');    }    var instanceMembers = isObject(options) && options.instanceMembers || {},      staticMembers = isObject(options) && options.staticMembers || {},      extend = isObject(options) && isFunction(options.extend) && options.extend,      prop;    //表示要构建的类的构造函数    function TargetClass() {      if (extend) {        //如果有要继承的父类        //就在每个实例中添加baseProto属性,以便实例内部可以通过这个属性访问到父类的原型        //因为copy函数导致原型链断裂,无法通过原型链访问到父类的原型        this.baseProto = extend.prototype;      }      if (isFunction(this.init)) {        this.init.apply(this, arguments);      }    }    //添加静态成员,这段代码需在原型设置的前面执行,避免staticMembers中包含prototype属性,覆盖类的原型    for (prop in staticMembers) {      if (hasOwn.call(staticMembers, prop)) {        TargetClass[prop] = staticMembers[prop];      }    }    //如果有要继承的父类,先把父类的实例方法都复制过来    extend && (TargetClass.prototype = copy(extend.prototype));    //添加实例方法    for (prop in instanceMembers) {      if (hasOwn.call(instanceMembers, prop)) {        //如果有要继承的父类,且在父类的原型上存在当前实例方法同名的方法        if (extend && isFunction(instanceMembers[prop]) && isFunction(extend.prototype[prop])) {          TargetClass.prototype[prop] = (function (name, func) {            return function () {              //记录实例原有的this.base的值              var old = this.base;              //将实例的this.base指向父类的原型的同名方法              this.base = extend.prototype[name];              //调用子类自身定义的实例方法,也就是func参数传递进来的函数              var ret = func.apply(this, arguments);              //还原实例原有的this.base的值              this.base = old;              return ret;            }          })(prop, instanceMembers[prop]);        } else {          TargetClass.prototype[prop] = instanceMembers[prop];        }      }    }    TargetClass.prototype.constructor = TargetClass;    return TargetClass;  }  return ClassBuilder})();//继承库演示部分var Employee = Class({  instanceMembers: {    init: function (name, salary) {        this.name = name;        this.salary = salary;        //调用静态方法        this.id = Employee.getId();      },      getName: function () {        return this.name;      },      getSalary: function () {        return this.salary;      },      toString: function () {        return this.name + '\'s salary is ' + this.getSalary() + '.';      }  },  staticMembers: {    idCounter: 1,    getId: function () {      return this.idCounter++;    }  }});var Manager = Class({  instanceMembers: {    init: function (name, salary, percentage) {        //通过this.base调用父类的构造方法        this.base(name, salary);        this.percentage = percentage;      },      getSalary: function () {        return this.base() + this.salary * this.percentage;      }  },  extend: Employee});var e = new Employee('jason', 5000);var m = new Manager('tom', 8000, 0.15);console.log(e.toString()); //jason's salary is 5000.console.log(m.toString()); //tom's salary is 9200.console.log(e.constructor === Employee); //trueconsole.log(m.constructor === Manager); //trueconsole.log(e.id); //1console.log(m.id); //2

原标题:详解Javascript的继承实现(二)

关键词:JavaScript

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。