JavaScript Weird Part (24) - 框架小叮嚀:偽裝命名空間

這一節是關於打開知名的框架原始碼經常會看到的東西。前面討論的那些主題,像是運算子、物件實體語法後,現在要學習偽裝命名空間 (faking namespaces)。

變數之間的衝突

在現代的程式語言,命名空間是變數和函數的容器,只是一個包裝物、一個容器。通常這是用來分開那些有著相同名稱的函數和變數。

在 JavaScript 裡,因為物件的本質,不需要命名空間這個功能,所以並沒有命名空間,但可以假裝。

1
2
3
4
var greet ='Hello';
var greet ='Hola';

console.log(greet);

有 2 個同樣名稱的變數,我們查詢它會得到的結果是什麼?在創造階段的變數會被設定為 undefined ,接著這些程式會逐行的依照順序執行,所以查詢變數的結果會是 hola

我們可以想像這兩個 greet 變數,被創造在兩個不同的 JavaScript 檔案中,一個是英文的打招呼,另一個框架是西文的打招呼。

這就會有問題,因為我們知道兩者都會設定它們的值。以這邊為例就是全域物件,然後覆寫另一個。這時命名空間就可以幫助我們,因為命名空間可以有一個容器裝英文問候語,另一個容器裝西文問候語。雖然 JavaScript 裡面沒有命名空間,但可以用物件做到。

以物件偽裝命名空間

我們可以建立物件成為屬性的容器避免這種衝突,而方法則是我們想要使用的東西。

1
2
3
4
5
6
//創造物件,使用物件實體語法
var english={}
var spanish={}

english.greet='Hello';
spanish.greet='Hola';

這兩變數雖然都叫 greet ,變數已經成為容器,確保我不會和其他 JavaScript 檔案,因為相同的全域命名空間而相互衝突覆寫。

深入運用

還可以進一步把不同的容器物件分級,例如我想要 english 有打招呼的方法的命名空間在裡面,我不能直接輸入 english.greetings.greet='Hello';

要記住 . 運算子是左相依性,表示左邊會先被執行。當. 運算子被呼叫,它會先在 english 裡面找greetings 變數,因為這是空的,所以找不到,而它會認定 undefined 根本不是一個物件,所以它不會在裡面找到 greet。必須再創造一個物件,在記憶體裡有一個物件,然後再連結greet

1
2
3
4
5
6
7
var english = {};
var spanish = {};
english.greetings = {};
english.greetings.greet = 'Hello';
spanish.greet = 'Hola';

console.log(english);

或者可以用物件實體語法初始化它,讓 greetings 裡面有另一個物件

1
2
3
4
5
6
7
8
9
var english = {
greetings:{
basic:'Hello'
}};
var spanish = {};

spanish.greet = 'Hola';

console.log(english);

物件實體語法可以快速建立,沒有得到 undefined 的錯誤,因為它們都已經被創造了。

我們可以用以上任何一種方式,但重點是已經在容器物件裡,包含函數、方法、變數、屬性和其他物件。

JavaScript 的偽裝命名空間,只是為了那些我們忘了別人已經寫好或自己寫好的程式碼,藉此分開程式碼和其他在全域命名空間的物件。

Powered by Hexo and Hexo-theme-hiker

Copyright © 2013 - 2020 CYC'S BLOG All Rights Reserved.

UV : | PV :