讀Ext之二(實用方法)


上篇看到Ext.extend,接着往下看。

Ext.namespace,用來管理Ext庫命名空間的方法

namespace : function(){
    var o, d;
    Ext.each(arguments, function(v) {
        d = v.split(".");
        o = window[d[0]] = window[d[0]] || {};
        Ext.each(d.slice(1), function(v2){
            o = o[v2] = o[v2] || {};
        });
    });
    return o;
},

 

多數情況下會這么使用

Ext.ns("Ext.util", "Ext.lib", "Ext.data");

Ext.ns是Ext.namespace的簡寫,這時會為全局的Ext變量掛上util,lib,data屬性,Ext.util,Ext.lib,Ext.data默認都是空的對象。當然也可以非Ext開頭的命名空間。

 

Ext.namespace內部使用了Ext.each,順藤摸瓜

each : function(array, fn, scope){
    if(Ext.isEmpty(array, true)){
        return;
    }
    if(!Ext.isIterable(array) || Ext.isPrimitive(array)){
        array = [array];
    }
    for(var i = 0, len = array.length; i < len; i++){
        if(fn.call(scope || array[i], array[i], i, array) === false){
            return i;
        };
    }
},

首先判斷第一個參數array是否為數組,如果為空直接返回。接着判斷array是否可迭代,對於數組、NodeList、 HTMLCollection都是可迭代的,即返回true。不可迭代的,如基本類型的字符串,數字等會將其包裝成數組。接着就是for循環,回調函數 fn,fn的執行上下文scope,scope如果沒有傳默認為array[i],即在fn內使用this取到集合的每一個元素。fn的第一個參數為集合 元素,第二個參數i為索引,第三個參數為被迭代元素自身。

 

最后還有個技巧,可以在fn內使用某個條件為false如 return i=3 來終止迭代,這時候會返回迭代最后一次的索引i。

可以看到 Ext.each 的用法與 JQuery.each 類似,不同之處在於Ext.each的第三個參數可以指定回調函數的執行上下文,jQuery.each 的第三個參數僅供庫內部使用。

 

Ext.each中使用了Ext.isEmpty方法,

isEmpty : function(v, allowBlank){
    return v === null || v === undefined || ((Ext.isArray(v) && !v.length)) || (!allowBlank ? v === '' : false);
},

Ext.isEmpty中有句(Ext.isArray(v) && !v.length),這里使用邏輯非運算符而沒有使用==,如(Ext.isArray(v) && v.length==0)。即當v是數組時還要檢測數組是否為空,如length為4,則!v.length就為false了。即數組不為空。

 

在看Ext.toArray方法,也是一個匿名函數自執行,執行后返回的function才是真正的Ext.toArray

toArray : function(){
 return isIE ?
     function(a, i, j, res){
         res = [];
         for(var x = 0, len = a.length; x < len; x++) {
             res.push(a[x]);
         }
         return res.slice(i || 0, j || res.length);
     } :
     function(a, i, j){
         return Array.prototype.slice.call(a, i || 0, j || a.length);
     }
}(),

可以看到實現時對瀏覽器進行了判斷,IE使用for循環的遍歷 偽數組 ,將其push到res中。非IE瀏覽器則使用Array.prototype.slice。

IE中為何不能使用Array.prototype.slice呢,對於NodeList等並非一個JavaScript object。會拋異常。懌飛 總結過。

然而,隨着IE9的發布,其已將javascript引擎內置在瀏覽器中,見圖

IE9 中Array.prototype.slice.call(NodeList) 已經不再拋異常了,可以使用其將NodeList等轉換為數組。因此Ext.isIE這個條件改為 Ext.isIE6||Ext.isIE7||Ext.isIE8 則較為合理了。之前DOM的錯誤實現也部分修復了,相關 Blog

 

Ext.iterate方法,

iterate : function(obj, fn, scope){
    if(Ext.isEmpty(obj)){
        return;
    }
    if(Ext.isIterable(obj)){
        Ext.each(obj, fn, scope);
        return;
    }else if(Ext.isObject(obj)){
        for(var prop in obj){
            if(obj.hasOwnProperty(prop)){
                if(fn.call(scope || obj, prop, obj[prop], obj) === false){
                    return;
                };
            }
        }
    }
},

這是一個通用迭代器,可以迭代數組,也可以是對象。當為迭代數組/偽數組 時其實是調用上面提到的 Ext.each。參數及使用方式也與 Ext.each 類似。

 

Ext.urlEncode,該方法用來將js對象序列化成查詢字符串

urlEncode : function(o, pre){
    var empty,
        buf = [],
        e = encodeURIComponent;

    Ext.iterate(o, function(key, item){
        empty = Ext.isEmpty(item);
        Ext.each(empty ? key : item, function(val){
            buf.push('&', e(key), '=', (!Ext.isEmpty(val) && (val != key || !empty)) ? (Ext.isDate(val) ? Ext.encode(val).replace(/"/g, '') : e(val)) : '');
        });
    });
    if(!pre){
        buf.shift();
        pre = '';
    }
    return pre + buf.join('');
},

里面使用了簡寫的 e = encodeURIComponent, encodeURIComponent 可以這么寫,其是核心js對象,document.getElementById 等BOM對象則不能這么簡寫。

 

Ext.urlDecode 則是將查詢字符串轉換成js對象。

Ext.urlAppend 添加字符串到查詢url。

 

Ext-2012-4-21.rar


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM