範圍 vs 存在
如果變數不存在,它就不會在範圍內。
範圍指的是
: 目前在執行的程式段落可以看到與操作某個識別碼。另一方面,存在代表
有一個識別碼保存了某些已經分配 ( 保留 ) 給它的記憶體。
語彙與動態範圍
我們舉個例子
1 | function test1(){ |
這是一般的程式碼,可以一目瞭然,不過有些時候不一定能明確
地看出範圍
1 | const x = 10; |
當我們定義 test( ) 的時候,變數 x 是存在的,但 y 不存在,然後我們宣告了 y 並呼叫 test( ) ,你可以看到,當 test 被呼叫時, x 在 test 的本文範圍內,但 y 不在。
全域變數
其實全域變數沒有這麼不好,不好的是濫用全域變數的部分。
1 | let a = 10; // 全域 |
這樣是沒有結果的,我們可以再把它放進物件裡
1 | let test = { |
這邊要想一個問題….如果物件裡的鍵超過一定的數量時……
1 | function f1(test){ |
區塊範圍
1 | console.log("before") |
這邊可以看得出作用範圍了
變數遮蓋
1 | { |
超出範圍會出現 undefined
在撰寫的時候也要考慮 嵌套
的問題
1 | { |
類似上面這種的要小心注意
函式、Closure( 閉包 )與語彙範圍
前面都在討論區域,一目瞭然的是在縮排後只需要看 { }
就可以知道它的範圍
但是在 modern JavaScript 裡,函式會根據它的需求而定義,他們被指派給變數或物件特性、加到陣列裡面、傳入傳出函式……
我們來看個 closure
的範例 ( closure 可以想成在函式周圍關閉範圍
)
1 | let test; |
立即呼叫函式運算式
我們先來看看這個東西長怎樣
1 | (function(){ |
這個東西就是 IIFE ( 立即呼叫函式運算式 )
。
我們直接來看個例子
1 | const msg = (function(){ |
很明顯的,這個變數 test 在 IIFE 的範圍
內是很安全的,我們可以從裡面傳出任何想要的東西。
雖然 ES6 的區塊範圍變數在某種程度上可以減少對 IIFE 的依賴
,但 IIFE 仍然很常見,而且當你想要建立一個 closure 時,並將某個東西傳出去還是很實用的。