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

简易_super实现

关键代码如下:

var Class=(function() {
            var initializing = false,
                fnTest = /xyz/.test(function() {
                    xyz;
                }) ? /\b_super\b/ : /.*/;
            var Class = function() {};
            Class.extend = function(prop) {
                var _super = this.prototype;
                initializing = true;
                var prototype = new this();
                initializing = false;
                for(var name in prop) {
                    prototype[name] = typeof prop[name] == "function" &&
                        typeof _super[name] == "function" && fnTest.test(prop[name]) ?
                        (function(name, fn) {
                            return function() {
                                var tmp = this._super;
                                this._super = _super[name];
                                var ret = fn.apply(this, arguments);
                                this._super = tmp;
                                return ret;
                            };
                        })(name, prop[name]) :
                        prop[name];
                }
                function Inner() {
                    if(!initializing&&this.init)
                        this.init.apply(this, arguments);
                }
                Inner.prototype = prototype;
                Inner.prototype.constructor = Inner;
                Inner.extend = arguments.callee;
                return Inner;
            };
            return Class;
        })();

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

var A=Class.extend({//父类
            init:function(){//不自动执行
                console.log('this is a init');
            },
            hello:function(){
                console.log('this is a.hello');
            },
            world:function(){
                console.log('this is a.world');
            }
        });
        var B=A.extend({//继承A
            init:function(){//自动执行
                console.log('this is b init');
            },
            hello:function(){
                this._super();
                console.log('this is b.hello');
            }
        });
        var b=new B();
        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方法。

回到顶部
我要评论

所有评论

返回
邮箱:
绑定
取消
×

我要评论

回复:

昵称:(昵称不超过20个字)

图片:

邮箱:
绑定邮箱后,若有回复,会邮件通知。
提交
还可以输入500个字