网络编程
位置:首页>> 网络编程>> JavaScript>> 《悟透JavaScript》之 甘露模型(3)

《悟透JavaScript》之 甘露模型(3)

作者:李战 来源:软件真谛 发布时间:2008-06-09 14:03:00 

标签:类,class,javascript,模型

其实,base()方法之所以要使用自身的caller属性,就是为了确定当前构造函数的层次,从而可以知道该调用更上层的构造函数。有没有别的办法来知道是那层构造函数调用了base()方法呢?残酷的事实告诉我们,除了函数自身的caller属性,没有办法知道是谁调用了自己。

既然改变不了别人,那就改变自己!我们为什么就不能在运行中改变base()自身呢?

事实上,第一层构造函数调用this.base()时,我们是可以过this.Type属性知道地一层构造函数的,而this.Type.Base就是第二层构造函数。只是,第二层构造函数又会调用this.base(),其本来是想调用第三层的构造函数,但再次进入base()函数时,就无法知晓构造函数的层次了。

如果我们在第一层构造函数调用进入this.base()时,先改变this.base本身,让其在下次被调用时能掉到第三层构造函数。完成这个变身动作之后再调第二层构造函数,而第二层构造函数再调用this.base()时就能调用到第三层构造函数了。这样,只要我们在每次的base()调用中都完成一个自我的变身动作,就可以按正确的顺序完成对构造函数的调用。这是多么有趣的调用方式啊!

    于是,我们可以将原来的base()函数改写成下面的形式:

object.prototype.base = function()  //调用基类构造函数
    {
        var Base = this.Type.Base;  //获取当前对象的基类  
        if(!Base.Base)  //若基类已没有基类
            Base.apply(this, arguments)     //则直接调用基类构造函数
        else    //若基类还有基类         
        {
            this.base = MakeBase(Base);     //先覆写this.base
            Base.apply(this, arguments);    //再调用基类构造函数
            delete this.base;               //删除覆写的base属性
        };
        function MakeBase(Type) //包装基类构造函数
        {
            var Base = Type.Base;
            if(!Base.Base) return Base; //基类已无基类,就无需包装
            return function()   //包装为引用临时变量Base的闭包函数
            {
                this.base = MakeBase(Base);     //先覆写this.base
                Base.apply(this, arguments);    //再调用基类构造函数
            };
        };
    };

原来的base()函数只有两行代码,而新的base()函数却又十几行代码。看来为了支持Opera浏览器确实也付出了代价,好在这些代码只有十来行,代价并不是太大。当然,如果无须支持Opera浏览器,也就不必用这个base()函数了。

在这个新的base()函数中,对this.base的覆写实际上只是在this对象身上创建了一个临时的base方法。这个临时方法暂时遮住了object.prototype.base方法,而object.prototype.base方法却一直存在。而每次对this.base的变身操作,都是针对这个临时的方法的。当所有层次构造函数的调用都完成之后,即可删除this对象的这个临时base方法。

其中的MakeBase()函数非常有意思,如果基类还有基类,它就返回一个闭包函数。下次this.base()被构造函数调用时,即调用的是这个闭包函数。但这个闭包函数又可能会调用MakeBase()形成另一个闭包函数,直到基类再无基类。

如果说这是递归调用呢?却并非那种函数自身对自身的直接或间接调用,而是调用一个函数却返回另一个函数,再调用返回的函数又会在其中产生新的返回函数。如果说是函数式编程中的高阶函数调用呢?这函数的嵌套阶数却是与类层次相关的不确定数,而每一个阶梯都有新生成的函数。

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com