ES6塊級做用域 js塊級做用域內部函數聲明的提高問題

塊級做用域的優勢javascript

避免變量衝突,好比程序中加載了多個第三方庫的時候,若是沒有妥善地將內部私有函數或變量隱藏起來,就很容易引起變量衝突;html

能夠方便的進行模塊管理;java

利於內存回收;(塊級做用域裏聲明的變量在塊級做用域執行完以後會所有銷燬)es6

es6中的塊級做用域chrome

以前在看360的培訓課程時,知道了{...}是個塊級做用域,錯誤的認爲{...}中聲明的函數變量都不會被外界訪問到,在看了你不知道的JS以後,發現並非這樣的。在塊級做用域中使用let聲明的變量外界沒法訪問到。函數

eg:post

var foo = true;
if (foo) {
let bar = foo * 2;
bar = something( bar );
console.log( bar );
} c
onsole.log( bar ); // ReferenceError

let 關鍵字能夠將變量綁定到所在的任意做用域中(一般是 { .. } 內部)。 換句話說, let爲其聲明的變量隱式地了所在的塊做用域。測試

可是這種方式是隱式的,若是沒有特別注意哪些塊級做用域中有綁定的變量,程序變大了以後,容易形成混亂,因此最好爲塊做用域顯式地創造塊來部分解決這個問題。url

1 var foo = true;
2 if (foo) { 3 { // <-- 顯式的快 4 let bar = foo * 2; 5 bar = something( bar ); 6 console.log( bar ); 7 } 8 } 9 console.log( bar ); // ReferenceError

 js塊級做用域內部函數聲明的提高問題spa

在讀《你不知道的js》這本書是看到了以下這段代碼:

複製代碼
1 foo(); // "b"
2 var a = true;
3 if (a) {
4 function foo() { console.log("a"); }
5 }
6 else {
7 function foo() { console.log("b"); }
8 }
複製代碼

書上說會打印出'b',由於一個普通塊內部的函數聲明一般會被提高到所在做用域的頂部, 這個過程不會像下面的代碼暗示的那樣能夠被條件判斷所控制。可是也說了這個行爲並不可靠, 在 JavaScript 將來的版本中有可能發生改變, 所以應該儘量避免在塊內部聲明函數。

博主試了在chrome上實驗了一下,結果報了VM451:1 Uncaught ReferenceError: a is not defined at <anonymous>:1:1這樣的錯誤,說明if語句中的foo函數聲明並無提高到全局做用域的頂部,因此井蓋是標準已經發生了改變,在塊級做用域中聲明的函數並不會提高到其父級做用域的頂部。

博主又打開了IE進行測試,發現IE11會和chrome同樣報ReferenceError的錯,但IE10及如下都會同書中同樣打印出'b'。鑑於新標準的支持程度並不高,仍是儘可能避免在塊級做用域內部聲明函數。

相關文章
相關標籤/搜索