看到的一个简单实现具有super作用的代码:

    简易_super实现

    关键代码如下:

    1. var Class=(function() {
    2.             var initializing = false,
    3.                 fnTest = /xyz/.test(function() {
    4.                     xyz;
    5.                 }) ? /\b_super\b/ : /.*/;
    6.             var Class = function() {};
    7.             Class.extend = function(prop) {
    8.                 var _super = this.prototype;
    9.                 initializing = true;
    10.                 var prototype = new this();
    11.                 initializing = false;
    12.                 for(var name in prop) {
    13.                     prototype[name] = typeof prop[name] == "function" &&
    14.                         typeof _super[name] == "function" && fnTest.test(prop[name]) ?
    15.                         (function(name, fn) {
    16.                             return function() {
    17.                                 var tmp = this._super;
    18.                                 this._super = _super[name];
    19.                                 var ret = fn.apply(this, arguments);
    20.                                 this._super = tmp;
    21.                                 return ret;
    22.                             };
    23.                         })(name, prop[name]) :
    24.                         prop[name];
    25.                 }
    26.                 function Inner() {
    27.                     if(!initializing&&this.init)
    28.                         this.init.apply(this, arguments);
    29.                 }
    30.                 Inner.prototype = prototype;
    31.                 Inner.prototype.constructor = Inner;
    32.                 Inner.extend = arguments.callee;
    33.                 return Inner;
    34.             };
    35.             return Class;
    36.         })();

    这里的_super()只有调用父类相同名字function的作用,没有替换父类this的作用,用法比较简单,大致如下:

    1. var A=Class.extend({//父类
    2.             init:function(){//不自动执行
    3.                 console.log('this is a init');
    4.             },
    5.             hello:function(){
    6.                 console.log('this is a.hello');
    7.             },
    8.             world:function(){
    9.                 console.log('this is a.world');
    10.             }
    11.         });
    12.         var B=A.extend({//继承A
    13.             init:function(){//自动执行
    14.                 console.log('this is b init');
    15.             },
    16.             hello:function(){
    17.                 this._super();
    18.                 console.log('this is b.hello');
    19.             }
    20.         });
    21.         var b=new B();
    22.         b.hello();

    这是一段非常有意思的实现super()的代码,让我们看看里面比较有意思的东西。

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

    这个比较有意思,/xyz/.test(function(){ xyz;})想测试的是是否可以检测到一个function里面是否包含特定的关键字,因为test右边是一个function,因此会先变成一个string进行测试,也就是/xyz/.test((function(){ xyz;}).toString()),正常情况返回true,如果可以检测的话,那么我们就能用相同的方法检测到一个function里面是否有关键字_super。/\b_super\b/两边的\b表示字符边界,表示是一个独立的_super,不是来自字符串的_super。

    关键过程

    整个过程还是非常巧妙的,每次调用一个extend,内部利用之前的类产生一个新的类,然后比较传入的方法列表和之前类的方法,如果相同的话就返回一个闭包,必包里面劫持了_super方法,让它指向原始类的方法,同时包含了传入的方法,执行的时候两个方法就会一起执行。

    上面的init方法执行的时机设计的也是非常巧妙,只有最后一个被实例化的类才会执行init方法。

    回到顶部
    我要评论

    所有评论

      相关文章