欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

关于JohnResig继承的实例讲解

程序员文章站 2022-06-11 15:49:22
最近我们课程到了面向对象这一章节,为了让大家更好的理解面向对象: var person = class.extend({ init: function(isdancin...

最近我们课程到了面向对象这一章节,为了让大家更好的理解面向对象:

var person = class.extend({
  init: function(isdancing){
    this.dancing = isdancing;
  },
  dance: function(){
    return this.dancing;
  }
});
 
var ninja = person.extend({
  init: function(){
    this._super( false );
  },
  dance: function(){
    // call the inherited version of dance()
    return this._super();
  },
  swingsword: function(){
    return true;
  }
});
 
var p = new person(true);
p.dance(); // => true
 
var n = new ninja();
n.dance(); // => false
n.swingsword(); // => true
 
// should all be true
p instanceof person && p instanceof class &&
n instanceof ninja && n instanceof person && n instanceof class

我认为上面的这种api设计是比较nice的,它达到了几个目的:一、所有的类继承自一个祖先class二、子类可以覆盖掉父类上的方法,当然了,可以通过super方法来调用父为的同名方法

下面是我的实现:

/* simple javascript inheritance
 * by john resig https://ejohn.org/
 * mit licensed.
 */
// inspired by base2 and prototype
(function(){
  var initializing = false, fntest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
 
  // the base class implementation (does nothing)
  this.class = function(){};
 
  // create a new class that inherits from this class
  class.extend = function(prop) {
    var _super = this.prototype;
   
    // instantiate a base class (but only create the instance,
    // don't run the init constructor)
    initializing = true;
    var prototype = new this();
    initializing = false;
   
    // copy the properties over onto the new prototype
    for (var name in prop) {
      // check if we're overwriting an existing function
      prototype[name] = typeof prop[name] == "function" &&
        typeof _super[name] == "function" && fntest.test(prop[name]) ?
        (function(name, fn){
          return function() {
            var tmp = this._super;
           
            // add a new ._super() method that is the same method
            // but on the super-class
            this._super = _super[name];
           
            // the method only need to be bound temporarily, so we
            // remove it when we're done executing
            var ret = fn.apply(this, arguments);        
            this._super = tmp;
           
            return ret;
          };
        })(name, prop[name]) :
        prop[name];
    }
   
    // the dummy class constructor
    function class() {
      // all construction is actually done in the init method
      if ( !initializing && this.init )
        this.init.apply(this, arguments);
    }
   
    // populate our constructed prototype object
    class.prototype = prototype;
   
    // enforce the constructor to be what we expect
    class.prototype.constructor = class;
 
    // and make this class extendable
    class.extend = arguments.callee;
   
    return class;
  };
})();