ECMAScript读Ext之一(实用方法)

第一句

window.undefined = window.undefined;  

  

兼容IE6以下的浏览器,有人 解释过了。

 

定义Ext全局变量

Ext = {
    version : '3.1.0'
};

专注这里没有动用var,不应用var阐明变量被认为是不佳的编程习惯,尤其是函数内阐明变量不写var更被称为是无边的Bug根源。这里则不会,因为变量Ext是该库唯一的全局变量(命名空间)。另外Ext源码中的变量阐明都助长了var。

 

给Ext添加静态apply方法,该形式是主导措施之一,会用其扩张Ext。

Ext.apply = function(o, c, defaults){
    // no "this" reference for friendly out of scope calls
    if(defaults){
        Ext.apply(o, defaults);
    }
    if(o && c && typeof c == 'object'){
        for(var p in c){
            o[p] = c[p];
        }
    }
    return o;
};

该形式有二种实施办法:

以此,只传o,c时直接将c上的享有属性/方法拷贝给o后回到;

这几个,defaults也传时,会将defaults,c上的装有属性/方法都拷贝给o。这里实现的很巧妙,同时有些绕人。

三个参数都传,会执行Ext.apply(o,
defaults),即我实现中调用自身。defaults为c,即当传六个参数时会直接开展对象拷贝。举个例子一目了解,在Ext.apply中加上一个输出语句

Ext.apply = function(o, c, defaults){
    // no "this" reference for friendly out of scope calls
    if(defaults){
        Ext.apply(o, defaults);
    }
    if(o && c && typeof c == 'object'){
        for(var p in c){
            alert(p); // 此处是添加的输出语句
            o[p] = c[p];
        }
    }
    return o;
};
var obj = {}, obj1 = {name:'jack'}, obj2 = {age:33};
Ext.apply(obj,obj1,obj2);

会发觉先弹出age,再是name。即先拷贝defaults,再是c。

 

接下去是个自实施的匿名函数,执行完后给Ext上增添许多实用性质或艺术。先定义了部分有些变量idSeed,浏览器判断之类。idSeed在做Dom缓存时用到。接下来,

if(isIE6){
    try{
        DOC.execCommand("BackgroundImageCache", false, true);
    }catch(e){}
}

这段代码用来化解IE6下css背景图不缓存bug,也 有人 解释过了。

 

吸纳就是一个Ext.apply(Ext,{…}),给Ext对象扩张许多实用性质及形式。

 

留意 Ext.isStrict
并非判断html文档格局为严刻情势,而是指正式形式,如<!DOCTYPE
HTML>阐明会重临true。关于文档形式猛击:http://hsivonen.iki.fi/doctype ,国内的 秦歌 翻译了该篇随笔。

 

Ext.isSecure 判断选择https或是其余。

 

Ext.applyIf
计划的很抢眼,它会把目的没有的习性和措施拷贝下来,已经部分则不拷贝。Ext.apply
则会覆盖已有的属性/方法。

ECMAScript
5已经披露1年多了,添加了有的新的API方法,如Array的indexOf,forEach等艺术,部分新本子浏览器已经支撑这些艺术来,但咱们想为老的浏览器扩大该方法。可能会这样写

var proto = Array.prototype;
if(!proto.indexOf){
    proto.indexOf = function(){
        // ...
    }
}
if(!proto.forEach){
    proto.forEach = function(){
        // ...
    }
}

即确保优先使用浏览器原生辅助的API方法,不协理的应用自定义实现的。但这边每趟都亟需判定下Array原型上是不是存在该措施。google
closure
  实现情势接近利用了三元运算符,每回都要判断下,相对丑陋。网上有部分对google
closure的 批评 及一些频率低下的 具体分析  ,批评者甚至包括大牛:Dmitry
Baranovskiy
 。相对来说,Ext.applyif则使的API的壮大很优雅。

 

Ext.id方法会为HTMLElement元素随机生成一个id,默认以”ext-gen”起先。

 

接下去是Ext.extend方法,该措施也是基本措施之一,整个ext框架继承都是以该方法来扩充的。该方法实现依靠于Ext.override,先看override

override : function(origclass, overrides){
    if(overrides){
        var p = origclass.prototype;
        Ext.apply(p, overrides);
        if(Ext.isIE && overrides.hasOwnProperty('toString')){
            p.toString = overrides.toString;
        }
    }
}

将对象overrides的富有属性/方法拷贝到类origclass的原型上。需要小心的是前边的if判断,IE中for
in不可以遍历对象的Object的toSting等办法,因而需要专门处理一下。我测试IE9
beta重写对象的内置方法如toString后是可用for in遍历的,见 for
in的缺陷
  。IE9
beta刚刚发表,不知今后Ext团队是不是会修改此处的判定。

 

Ext.extend是js继承最经典的实现模式了,我曾经模仿其(简化版)应用在 51ditu 。

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){
        if(Ext.isObject(sp)){
            overrides = sp;
            sp = sb;
            sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};
        }
        var F = function(){},
            sbp,
            spp = sp.prototype;

        F.prototype = spp;
        sbp = sb.prototype = new F();
        sbp.constructor=sb;
        sb.superclass=spp;
        if(spp.constructor == oc){
            spp.constructor=sp;
        }
        sb.override = function(o){
            Ext.override(sb, o);
        };
        sbp.superclass = sbp.supr = (function(){
            return spp;
        });
        sbp.override = io;
        Ext.override(sb, overrides);
        sb.extend = function(o){return Ext.extend(sb, o);};
        return sb;
    };
}(),

完全浏览,可以看来 Ext.extend
的落实是通过一个匿名函数执行,执行后归来function,那一个function才是的确的Ext.extend。

匿名函数中有五个村办函数io,oc。这种协会代码的不二法门要命简便,通过匿名函数自举行,在匿名函数中您可以做任何复杂的操作,最终的目标重返需要的接口函数或类。

 

有多少个参数,sb、sp、overrides分别表示subClass(子类)、superClass(父类)及覆盖子类的部署参数。

 

以下分两种情况琢磨,第一,二种境况Ext.extend的第二个参数都是目的类型

 

1, Ext.extend不光是用来落实类继承的,还可以够用来写类,一年前 讨论 过
。 

2, 用来扩展Ext库自身类,这种场合是相比较频繁的

MyGridPanel = Ext.extend(Ext.grid.GridPanel, {
    constructor: function(config) {
        MyGridPanel.superclass.constructor.apply(this, arguments);
    },
    yourMethod: function() {
        // etc.
    }
});

此间以Ext.grid.GridPanel为底蕴,生成了一个新类MyGridPanel

 

3,
真正意义类继承,即首先,二个参数都是类(function)。1年前也总括过js咋样贯彻 继承 及 工具函数 。

 

篇幅已经很长了,重点说下 Ext.apply, Ext.applyif, Ext.override,
Ext.extend 的区别 :

 

Ext.apply, Ext.applyif, Ext.override
都是对对象 举行扩张的措施,Ext.extend则是对 操作的形式。

 

Ext.apply 扩充时对曾经存在的性能/方法会被遮住掉,
平时用它来扩张普通对象.

Ext.applyif
扩大时不会覆盖已经存在的属性/方法,平时用它来增添主旨js,如Array.prototype,String.prototype等。

Ext.override 扩充某一个类的原型,可以覆盖toString方法。

 

Ext.extend 用来写类或持续,或者说用来扩充类。

 

 

Ext-2012-4-21.rar