每天一点点-EXT源码分析之四

来源:互联网 发布:手机淘宝价格字体 编辑:程序博客网 时间:2024/05/19 13:15
extend : function(){            // inline overrides            var io = function(o){                for(var m in o){                    this[m] = o[m];                }            };            var oc = Object.prototype.constructor;            return function(sb, sp, overrides){              //判断第二个参数为object时,就是判断是否传入的是二个参数                if(Ext.isObject(sp)){                    overrides = sp;//overides是第二个参数了(对象类型)                    //sp是第一个参数了                    sp = sb;                     //sb是一个构造函数了                          sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};                }                var F = function(){},                    sbp,                    spp = sp.prototype;                //用F代替超类,目的是改变sb的prototype不会改变sp的prototype                F.prototype = spp;                //下面2行,就如上面的例子一样,很典型的js继承方式                sbp = sb.prototype = new F();                sbp.constructor=sb;                //给子类添加一个属性,方便指回父类的原型对象                sb.superclass=spp;                if(spp.constructor == oc){                    spp.constructor=sp;                }              //给sb添加override静态方法               sb.override = function(o){                    Ext.override(sb, o);                };                sbp.superclass = sbp.supr = (function(){                    return spp;                });               //给子类添加override实例方法             sbp.override = io;                                Ext.override(sb, overrides);                //为sb添加静态方法                sb.extend = function(o){Ext.extend(sb, o);};                return sb;            };        }(),

 接着上回笔记。
Ext.extend()这个函数看了近4个小时才感觉明白了个大概其,一个原因是自己功力不够,另一个原因是Jack Slocum这个函数写得确实是吊。

复习一下js的继承吧。
js其实并不是标准的面向对象语言,它只是模拟继承,方法多种多样,非常复杂。
一般js实现OO方式的继承,是重写子类的prototype,让父类的实例成为子类的prototype对象,那么这个子类就有父类的实例属性,而这个父类的实例同时又有_proto_指向自己的prototype对象,那么也就是说,这个子类也就间接有了父类prototype对象里的属性。
注意是间接的方式:SubClass.prototype---->superInstance,superInstance._proto_---->SuperClass.prototype
由于子类的prototype对象现在指向了父类的prototype对象,所以constructor此时指向了父类的构造函数,这当然不是符合逻辑的,所以还要把constrctor重新指回子类的构造函数。
Ext实际是用的下面这种继承方式
一个例子:
function Sup(name){        this.name=name;}Sup.prototype.fn=function(){      alert("父类原型中方法")}function Sub(age){       Sup.call(this);//防止一个类的不同实例共享属性,也就是不要把从父类继承的属性放到prototype对象里,用对象的反射调用(this,用特定的上下文调用父类的构造函数,引入其属性),就可以解决       这个问题       this.age=age;}



EXT其实是提供了2中继承的方式。
1,对象的继承。(Ext.apply)
其实就是把父对象的属性方法复制到子对象中。
2,类的继承。(Ext.extend)
把父类的属性或方法复制到子类的原型对象中。

OK了,看会EXT的源码把

 
再次感叹,这个函数,写得确实很有水平。
首先,它是一个立即执行的函数,返回其中的闭包,这样可以提高效率和保证期变量的私有性。
其实,我们实际使用的function(sb, sp, overrides)这个函数。
其次,这个函数有俩种方式调用。
1,二个参数版本(第一个参数:函数类型,第二个参数:对象类型)
2,三个参数版本(第一个 参数:子类,第二个参数:父类,第三个参数:对象类型)
理解,写在注解中。

extend : function(){
            // inline overrides
            var io = function(o){
                for(var m in o){
                    this[m] = o[m];
                }
            };
            var oc = Object.prototype.constructor;

            return function(sb, sp, overrides){
              //判断第二个参数为object时,就是判断是否传入的是二个参数 
              if(Ext.isObject(sp)){
                    overrides = sp;//overides是第二个参数了(对象类型)
                    //sp是第一个参数了
                    sp = sb;
                     //sb是一个构造函数了     
                    sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};
                }
                var F = function(){},
                    sbp,
                    spp = sp.prototype;
                //用F代替超类,目的是改变sb的prototype不会改变sp的prototype
                F.prototype = spp;
                //下面2行,就如上面的例子一样,很典型的js继承方式
                sbp = sb.prototype = new F();
                sbp.constructor=sb;
                //给子类添加一个属性,方便指回父类的原型对象
                sb.superclass=spp;
                if(spp.constructor == oc){
                    spp.constructor=sp;
                }
              //给sb添加override静态方法
              sb.override = function(o){
                    Ext.override(sb, o);
                };
                sbp.superclass = sbp.supr = (function(){
                    return spp;
                });
               //给子类添加override实例方法
            sbp.override = io;
               
                Ext.override(sb, overrides);
                //为sb添加静态方法
                sb.extend = function(o){Ext.extend(sb, o);};
                return sb;
            };
        }(),