深入剖析js命名空間函式namespace

2022-05-03 04:15:08 字數 3305 閱讀 3147

生成命名空間的方法繫結到jquery上

阿里員工寫的開源資料庫連線池的druid的源**時,發現了其中在jquery的原**中又定義了乙個命名空間的函式:$.namespace(),其**如下:

$.namespace("druid.index"); druid.index=function(), submit:function() } } //使用命名空間的函式 druid.index.login(); druid.index.submit();

這樣的話,就不會在全域性變數區,引入很多的函式,將所有要使用的函式已經變數都放入了命名空間druid.index中,避免了不同js庫中的函式名的衝突。

但是namespace函式的定義如何理解呢?

$.namespace = function

() ;

o=o[d[j]];

} }

return

o;

};

思考了很久,思考的過程明白乙個額外的知識點:window這個引用的是不可覆蓋的。比如我們看下面的**:

console.log(window);

window = {};

console.log(window);

window = null;

console.log(window);

window = undefined;

console.log(window);

列印的結果都是 window, 而不會是 null 或者 undefined。也就是說window這個名稱,實質上是個引用或者說指標,他指向heap上的全域性window物件,stack上的window引用指向heap上的全域性window物件,這個指向關係是不可覆蓋,不可修改的。上面我修改了stack上的window,檢視讓他指向null物件,但是修改是無效的。

我們利用firebug來除錯看看命名空間到底是如何實現的,我們一步一步的接近目標,先看如下**:

(function

(); console.log(o);

//列印window

console.log(o.druid); //

列印 object {}

})();

firebug中顯示的物件為:

上面這個結果應該很好理解,因為 o指向了window,所以o.index = {}; 也就相當於 window.index = {}; 在window上定義了乙個名叫index的物件。

下面我們在上面的**上加碼,在前進一步,接著看:

(function

(); console.log(o);

//列印window

console.log(o.druid); //

列印 object {}

o =o.druid;

console.log(o);

//列印 object {}

console.log(window); //

列印window

console.log(o.druid); //

列印 undefined

})();

上面的**中:o = o.druid; 之後,因為 o 是指向 window,為什麼console.log(o);  列印 object {};而 console.log(window); 列印輸出window呢?這裡的原因是,沒有理解引用的含義。o 和 window 都是stack上的乙個變數,他們都指向heap上的全域性window物件,我們修改 o 這個引用,讓它指向另外的乙個空物件,而這並不會同時修改stack上的window這個引用的指向。也就是就像兩條繩子 a, b 都指向一條船,我讓其中的一條繩子b指向第二條船,並不會影響繩子a還指向第一條船。

o = o.druid; 執行之後,o 不再執行window物件了,而是指向了window.druid物件,那麼最後的console.log(o.druid);為什麼列印輸出 undefined 呢?很簡單,因為 o 已經指向了 window.druid; 而window.druid是個空物件,其下並沒有個druid的屬性,所以自然就列印輸出 undefined 了。

也就是說最後的console.log(o.druid); 就相當於 console.log(window.druid.druid);

(function

(); console.log(o);

//列印window

console.log(o.druid); //

列印 object {}

o =o.druid;

console.log(o);

//列印 object {}

console.log(window); //

列印window

console.log(o.druid); //

列印 undefined

o.index ={};

console.log(o.index);

//列印 object {}

o =o.index;

console.log(o.index);

//undefined

})();

對應的firebug中顯示的物件為:

我們看到了已經形成了我們需要的命名空間:window.druid.index ,其實命名空間是使用物件鏈條來實現的。

因為 o = o.druid; 之後,o 已經指向了 window.druid ,那麼 o.index = {}; 就相當於 window.druid.index = {};

而 後面的 o = o.index; 又將 o 物件變成了乙個空物件,不再指向 window.druid,列印乙個空物件的 index 屬性自然就輸出 undefined.

到這裡已經就可以完全理解namespace函式的定義了。

其實核心知識點的有三條:

1)利用了 window 這個特殊引用的不可覆蓋性,不可修改;

2)命名空間其實是物件鏈條來模擬的;

3)理解引用的含義:引用是個在stack上的變數,可以修改它指向不同的物件,要訪問或者說修改他指向的物件,必須使用 「.」 點操作符,比如 o.index ={}; 而單純的修改 o ,比如 o = {}; 並不會修改他指向的物件,因為 沒有訪問到他指向的物件,怎麼能修改到他指向的物件呢?

命名空間剖析

框架概覽 net framework 主要包括兩個部分 clr 通用語言進行時 和fcl 框架類庫 其中clr是.net framework的基礎,提供了包括記憶體管理,執行緒管理和遠端處理等核心服務 fcl是乙個機遇物件導向的可重用型別集合,用於支援多種應用的快速開發,例如 asp.net web...

JS命名空間

命名空間namespace 某些語言中叫package 是乙個在靜態語言中常見的概念。它可以幫助我們更好地整理 並可避免命名衝突。舉乙個簡單的例子,如果有兩個人都叫小明,我們很難區分和引用這兩個人。但如果我們在他們前面加上命名空間,比如 北京的小明和上海的小明,那麼區分起來就容易的多了,也不會因為重...

JS命名空間with

眾所周知乙個頁面可能會被很多人開發,那麼這時候就有乙個問題,那就是命名的重複 變數,函式名 所以為了解決這個問題,命名空間就應用而生了。可以先看如下 var org jerry groupb org.groupa.jerry.name那麼此時可以發現,如果要使用某個變數,那麼要層層呼叫,但是這回很麻...