您好,登錄后才能下訂單哦!
這篇“ES6塊級作用域是什么及怎么應用”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“ES6塊級作用域是什么及怎么應用”文章吧。
ES6
中新增了塊級作用域。塊作用域由 { }
包括,if
語句和 for
語句里面的 { }
也屬于塊作用域。
第一種場景:內部變量會覆蓋外部變量
var time = new Date() function fx () { console.log(time) // undefined if (false) { var time = 'hello' } } fx()
{ var a = 1 console.log(a) // 1 } console.log(a) // 1 // 通過var定義的變量可以跨塊作用域訪問到。
第二種場景:用來計數的循環變量泄漏為全局變量
for
循環中的用 var
定義的變量在外部作用域可以訪問
for (var i = 0; i < 3; i++) { } for (let j = 0; j < 3; j++) { } // 3 console.log(i); // Uncaught ReferenceError: j is not defined console.log(j);
if
語句中 var
定義的變量在外部作用域可以訪問
if(true)
與if (false)
的區別
if(true)
中的賦值語句會被執行,所以a
打印出來是3
if(false)
中的賦值語句不會被執行,但聲明的變量var b
會由于變量提升,提升到作用域的頂層,所以打印出來是undefined
if (true) { var a = 3 } if (false) { var b = 3 } // 3 console.log(a); // undefined console.log(b); if (true) { let c = 3 } // Uncaught ReferenceError: c is not defined console.log(c);
function fxFn () { // 這是一個塊級作用域 let fx = 'fx is a great girl' if (true) { // 這是一個塊級作用域 let fx = 'fx is 18 years old' } console.log(fx) // fx is a great girl } fxFn() // 塊級作用域之間相互不影響
ES6 允許塊級作用域的任意嵌套。
{{{{ { let fnn = 'Hello' } console.log(fnn); // 報錯 }}}};
上面代碼使用了一個五層的塊級作用域,每一層都是一個單獨的作用域。第四層作用域無法讀取第五層作用域的內部變量。
內層作用域可以定義外層作用域的同名變量。
{{{{ let fnn = 'Hello'; { let fnn = 'Hello' } }}}};
塊級作用域的出現,實際上使得獲得廣泛應用的匿名立即執行函數表達式(匿名 IIFE
)不再必要了。
// IIFE 寫法 (function () { var tmp = '...'; // ... }()); // 塊級作用域寫法 { let tmp = '...'; // ... }
ES5
規定,函數只能在頂層作用域和函數作用域之中聲明,不能在塊級作用域聲明。
// 情況一 if (true) { function f() {} } // 情況二 try { function f() {} } catch(e) { // ... }
上面兩種函數聲明,根據 ES5
的規定都是非法的。
但是,瀏覽器沒有遵守這個規定,為了兼容以前的舊代碼,還是支持在塊級作用域之中聲明函數,因此上面兩種情況實際都能運行,不會報錯。
ES6
引入了塊級作用域,明確允許在塊級作用域之中聲明函數。ES6
規定,塊級作用域之中,函數聲明語句的行為類似于 let
,在塊級作用域之外不可引用。
function f() { console.log('I am outside!'); } (function () { if (false) { // 重復聲明一次函數f function f() { console.log('I am inside!'); } } f(); }());
上面代碼在 ES5
中運行,會得到“I am inside!
”,因為在 if
內聲明的函數 f
會被提升到函數頭部,實際運行的代碼如下。
// ES5 環境 function f() { console.log('I am outside!'); } (function () { function f() { console.log('I am inside!'); } if (false) { } f(); }());
ES6
就完全不一樣了,理論上會得到“I am outside!
”。因為塊級作用域內聲明的函數類似于 let
,對作用域之外沒有影響。
但是,如果你真的在 ES6
瀏覽器中運行一下上面的代碼,是會報錯的,這是為什么呢?
// 瀏覽器的 ES6 環境 function f() { console.log('I am outside!'); } (function () { if (false) { // 重復聲明一次函數f function f() { console.log('I am inside!'); } } f(); }()); // Uncaught TypeError: f is not a function
上面的代碼在 ES6
瀏覽器中,都會報錯。
原來,如果改變了塊級作用域內聲明的函數的處理規則,顯然會對老代碼產生很大影響。為了減輕因此產生的不兼容問題,ES6 規定,瀏覽器的實現可以不遵守上面的規定,有自己的行為方式
允許在塊級作用域內聲明函數。
函數聲明類似于var
,即會提升到全局作用域或函數作用域的頭部。
同時,函數聲明還會提升到所在的塊級作用域的頭部。
注意,上面三條規則只對 ES6
的瀏覽器實現有效,其他環境的實現不用遵守,還是將塊級作用域的函數聲明當作 let
處理。
根據這三條規則,瀏覽器的 ES6
環境中,塊級作用域內聲明的函數,行為類似于 var
聲明的變量。上面的例子實際運行的代碼如下。
// 瀏覽器的 ES6 環境 function f() { console.log('I am outside!'); } (function () { var f = undefined; if (false) { function f() { console.log('I am inside!'); } } f(); }()); // Uncaught TypeError: f is not a function
考慮到環境導致的行為差異太大,應該避免在塊級作用域內聲明函數。如果確實需要,也應該寫成函數表達式,而不是函數聲明語句。
// 塊級作用域內部的函數聲明語句,建議不要使用 { let a = 'secret'; function f() { return a; } } // 塊級作用域內部,優先使用函數表達式 { let a = 'secret'; let f = function () { return a; }; }
如果沒有大括號,JavaScript
引擎就認為不存在塊級作用域。
// 第一種寫法,報錯 if (true) let x = 1; // 第二種寫法,不報錯 if (true) { let x = 1; }
上面代碼中,第一種寫法沒有大括號,所以不存在塊級作用域,而let只能出現在當前作用域的頂層,所以報錯。第二種寫法有大括號,所以塊級作用域成立。
函數聲明也是如此,嚴格模式下,函數只能聲明在當前作用域的頂層。
// 不報錯 'use strict'; if (true) { function f() {} } // 報錯 'use strict'; if (true) function f() {}
以上就是關于“ES6塊級作用域是什么及怎么應用”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。