偽裝命名空間
![偽裝命名空間]()
命名空間在現在的程式語言是變數與函數的容器,通常是用來維持變數和函數的名稱分開避免 A 感染到 B,但 JavaScript 其實並沒有命名空間這種東西,可是我們可以利用物件來偽裝命名空間。
課程提供了一個範例 ↓
1 2 3 4
| var greet = 'Hello!'; var greet = 'Hola!';
console.log(greet);
|
那 console.log
會輸出哪一個?
我們都知道所有 JavaScript 中的變數及函數都會歷經創造階段 (Hoisting),並且所有變數都會被賦予**預設值 (undefined)**,當我們若將程式拆開來看就會比較清楚 ↓
1 2 3 4 5
| var greet;
greet = 'Hello!'; greet = 'Hola!'; console.log(greet);
|
![greet]()
一般來講我們可能會使用到相同的變數名稱,在其他程式語言中可以使用 命名空間 (namespace) 來解決相同變數或函數衝突問題,但在 JavaScript 並沒有 命名空間 (namespace) 這種東西,所以我們可以利用物件來製作偽裝命名空間,就像這樣 ↓
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var greet;
greet = 'Hello!'; greet = 'Hola!'; console.log(greet);
var english = {}; var spanish = {};
english.greet = 'Hello!'; spanish.greet = 'Hola!';
console.log(english); console.log(spanish);
|
這樣子就可以持有兩個相同名稱的變數 (greet
),而這也就是所謂的偽裝命名空間,這樣做的好處就是可以閃過變數衝突問題,所以其實是在利用物件的特性來製作的。
但是不能這樣子寫 ↓
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var greet;
greet = 'Hello!'; greet = 'Hola!'; console.log(greet);
var english = {}; var spanish = {};
english.greetings.greet = 'Hello!'; spanish.greet = 'Hola!';
console.log(english); console.log(spanish);
|
![致命錯誤]()
這樣是會出現一個致命錯誤的,why?首先在點運算子相同優先性的狀況下就會考慮相依性,這是我們理解的觀念,而點運算子的相依性是左相依性,所以會從左邊開始執行,所以 english
會在裡面尋找一個叫 greetings
的變數,但是因為 greetings
還沒有被建立,所以這會是空的,那該如何解決呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| var greet;
greet = 'Hello!'; greet = 'Hola!'; console.log(greet);
var english = { greetings: {}, }; var spanish = {};
english.greetings.greet = 'Hello!'; spanish.greet = 'Hola!';
console.log(english); console.log(spanish);
|
![greetings]()
這樣就可以解決問題了,回頭講講上面的原因,為什麼不能這樣寫 ↓
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var greet;
greet = 'Hello!'; greet = 'Hola!'; console.log(greet);
var english = {}; var spanish = {};
english.greetings.greet = 'Hello!'; spanish.greet = 'Hola!';
console.log(english); console.log(spanish);
|
首先剛剛有講到點運算子是左相依性,所以 english.greetings
先被執行完畢了,但是 english
底下並沒有 greetings
,所以 JavaScript 將它變成預設值 undefined
,那程式碼就會變成這樣 ↓
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var greet;
greet = 'Hello!'; greet = 'Hola!'; console.log(greet);
var english = {}; var spanish = {};
undefined.greet = 'Hello!'; spanish.greet = 'Hola!';
console.log(english); console.log(spanish);
|
那 undefined
本身就不是一個物件,所以就會跳錯哩~
圖源
JavaScript 全攻略:克服 JS 奇怪的部分