关于javascrip 类继承封装

下面这段代码是javascrip inherit 的一段继承的代码我倒持了一早上才搞明白其中的道理,最主要是里面有一些平时我们不怎么使用的函数和方法。比较迷惑人。现在我就针对这些代码做一些自己的注解:(当然他也有一些英文注解,但是不够清楚明白,我们也可以后期改造这个方法,让他更适合我们自己的使用)


/* Simple JavaScript Inheritance

 * By John Resig http://ejohn.org/

 * MIT Licensed.

 */

// Inspired by base2 and Prototype

(function(){

//方法在继承的时候会类似java等具有继承特性的语言一样,初始化上级父类中的方法和属性。

//initializing 这个属性主要是用来作为是否初始化过的一个变量。

  var initializing = false;

//这个是需要特殊对待的一段代码,这段代码在后面进行覆盖父类属性中用到了判断是否是函数,且是否存在上级父类方法的判断条件。如果对这个有什么疑问查看我转载的另一篇关于该代码的博文。

   fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;

 

  // The base Class implementation (does nothing)

  //基类的实现,这个地方只是声明一下Class基类而已,啥事也不干。

  this.Class = function(){};

 

  // Create a new Class that inherits from this class

  //这是声明Class基类的继承方法,同时带着的参数需要特殊说明:prop就是后面我们调用extend方法的时候传进去的参数。

  Class.extend = function(prop) {

    //_super 是特别有用的属性。是用来存储父类属性的数组。使得后面继承的类可以用this._super.xxx调用父类属性。

    var _super = this.prototype;

   

    // Instantiate a base class (but only create the instance,

    // don‘t run the init constructor)

    initializing = true;

//首先创建一个自己的对象,这样就会把对象的所有属性拷贝在了prototype中,在第一次调用Class.extend时,new this()生成的是没有特殊属性的父类对象。

    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

     //检查父类的方法,如果父类存在相同名字的方法则覆盖父类的方法。在javascript里面方法参数是可以多传或者少传,有点像java里面的动态参数。所以不存在方法多态(重载),相同名字就直接重写了。

      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

            //创建自己的super的引用

            this._super = _super[name];

           

            // The method only need to be bound temporarily, so we

            // remove it when we‘re done executing

            //这里涉及到了一个很陌生的方法是apply,和这个方法很类似的方法有一个call方法,也就是fn的方法重新绑定一下参数,this指的是本段funciton本身。arguments指的是传入的参数。也就是无论fn中传入什么参数,这里返回的ret就会绑定参数。

            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);

    }

   //将重新生成的属性赋给Class,这个Class不是基类Class而是生成的对象自己。也就是可以

    // Populate our constructed prototype object

    Class.prototype = prototype;

   //构造函数引用

    // Enforce the constructor to be what we expect

    Class.prototype.constructor = Class;

 //callee这个方法会把本段extend方法赋给Class的extend方法,这样新生成的类也可以实现继承

    // And make this class extendable

    Class.extend = arguments.callee;

   

    return Class;

  };

})();


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。