天天看點

《Ext詳解與實踐 v3》閱讀補充資料:配置設定命名空間

現代Web

前端的特征之一是由不止一個庫所組成的,或者沒有達到稱為“庫”的标準,有可能就是僅僅若幹個小部件(Widget)

、某一段的JavaScript

代碼(Snippets)

所組成。從開發者的角度而言,你所産生的代碼有很大的機會與其他的代碼産生沖突,因為我們清楚JavaScript

是一門格外自由的語言,允許全局變量星羅棋布地存在,這樣的話太多就極容易造成污染。是以有必要采用一定措施降低這種沖突發生的可能性。

extjs.com

的官方論壇它目前采用了來自三方面的程式(如上

圖一

):

Ext

精減版(ext.js)

Google

流量分析(urchin.js)

論壇自帶的vRulletin

腳本(vbulletin_*.js)

如果有新需求,還可能加入其他第三方的JavaScript

庫。進入Firebug

的Dom

頁籤觀察,位于window

對象下面存放的變量數以百計,這些變量正是Ajax

庫所帶來到JavaScript

頂層全局環境的。JavaScript

是一門帶有變量作用域的語言,任何一個變量若不加var

則可表示為一個全局成員,就加入在window

對象(即全局空間)下。

庫并沒有使用太多的全局變量在裡面。任何一個它的類均安排在“Ext

對象底下,是以說整個架構隻使用了一個全局變量Ext

(如下

圖)。

命名空間(Namespace)

表示辨別符(Identifier)

的上下文(Context)

。一個辨別符可在多個命名空間中定義,它在不同命名空間中的含義是互不相幹的。這樣,在一個新的命名空間中可定義任何辨別符,它們不會與任何已有的辨別符發生沖突,因為已有的定義都處于其他命名空間中。把實作的代碼安排在一個特定的命名空間中,由各個類或單例構成,這樣的JavaScript

編碼風格不僅有良好的組織,直覺可維護的優點,而且還能有避免它方代碼幹擾、竄改的好處。“為變量建立其命名空間,這樣類就有了“安身之所”,不是飄蕩四處的“全局變量。”(摘自API

文檔)”。

提示: 筆者有一次就 API 翻譯的問題與參與人員發生小誤會,有兩份檔案都是 DataField.js ,分别在不同的包中,一個是 /widget/DataField.js ;另外一個是 /widget/form/DataField.js 。但筆者誤認為“未翻譯的”當作“已翻譯的”,這樣大家碰頭時就發生誤會了。看來還真是命名空間相沖突而導緻的結果,最後大家認真溝通下才把問題解釋清楚。

使用Ext.ns()

可以實作簡單的命名空間聲明方式,其全稱是Ext.namespace()

。Ext.ns()

用法如下

所示:

/* Ext.namespace會建立下列對象,若不存在的話 */

Ext.namespace('App', 'App.panel', 'App.data');

/* // 等價于注釋的語句

if (!App)

    App = {};

if (!App.form)

    App.form = {};

if (!App.data)

    App.data = {};

*/

/* 定義App.form包内部的新類SamplePanel */

App.panel.SamplePanel = Ext.extend(Ext.Panel, {

    initComponent: function(){

        /*component configuration code here! */

        App.form.SamplePanel.superclass.call(this);

    }

});

Ext.namespace()

傳入的參數中不能包含

ECMAScript

關鍵字,例如“

com.extjs.long

中的

long

是關鍵字,不能被

ns

方法執行。

方法的關鍵地方之一是利用了eval

函數解析字元串為對象,若在一些不支援eval()

函數環境(如Adobe

AIR

的安全沙箱下),可參考YUI

庫的namespace()

方法,主要原理是JavaScript

的對象“索引式”聲明增加Hash

表内元素,缺點是有第一個因子項的限制,因為該方法中須明确命名空間的第一個因子項。

// Yahoo! UI namespce方法源碼

namespace = function() {

        YAHOO = {};  // YAHOO是全局變量

        var a=arguments, o = null, i, j, d;

        // 周遊所傳入的參數。JavaScript的參數具有參數個數不确定性

        for (i=0; i<a.length; i=i+1) {

            d = a[i].split(".");// 傳回數組,每個字元串以.分割開後,成為數組的元素

            o = YAHOO;

            // 規定所有的命名空間均以YAHOO開頭,如果依據顯式聲明則忽略

            for (j=(d[0] == "YAHOO") ? 1 : 0; j<d.length; j=j+1) {

                o[d[j]]=o[d[j]] || {}; // 跳過目前已經存在的對象

                o=o[d[j]]; // 移位到數組的下一個元素

            }

        }

        return o;

}

一書(覆寫包含2.2/3.03的版本)的全面介紹。

繼續閱讀