這篇“ES6塊級(jí)作用域是什么及怎么應(yīng)用”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“ES6塊級(jí)作用域是什么及怎么應(yīng)用”文章吧。
創(chuàng)新互聯(lián)從2013年創(chuàng)立,先為云浮等服務(wù)建站,云浮等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為云浮企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。
ES6
中新增了塊級(jí)作用域。塊作用域由 { }
包括,if
語句和 for
語句里面的 { }
也屬于塊作用域。
第一種場景:內(nèi)部變量會(huì)覆蓋外部變量
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定義的變量可以跨塊作用域訪問到。
第二種場景:用來計(jì)數(shù)的循環(huán)變量泄漏為全局變量
for
循環(huán)中的用 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)
的區(qū)別
if(true)
中的賦值語句會(huì)被執(zhí)行,所以a
打印出來是3
if(false)
中的賦值語句不會(huì)被執(zhí)行,但聲明的變量var b
會(huì)由于變量提升,提升到作用域的頂層,所以打印出來是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 () { // 這是一個(gè)塊級(jí)作用域 let fx = 'fx is a great girl' if (true) { // 這是一個(gè)塊級(jí)作用域 let fx = 'fx is 18 years old' } console.log(fx) // fx is a great girl } fxFn() // 塊級(jí)作用域之間相互不影響
ES6 允許塊級(jí)作用域的任意嵌套。
{{{{ { let fnn = 'Hello' } console.log(fnn); // 報(bào)錯(cuò) }}}};
上面代碼使用了一個(gè)五層的塊級(jí)作用域,每一層都是一個(gè)單獨(dú)的作用域。第四層作用域無法讀取第五層作用域的內(nèi)部變量。
內(nèi)層作用域可以定義外層作用域的同名變量。
{{{{ let fnn = 'Hello'; { let fnn = 'Hello' } }}}};
塊級(jí)作用域的出現(xiàn),實(shí)際上使得獲得廣泛應(yīng)用的匿名立即執(zhí)行函數(shù)表達(dá)式(匿名 IIFE
)不再必要了。
// IIFE 寫法 (function () { var tmp = '...'; // ... }()); // 塊級(jí)作用域?qū)懛? { let tmp = '...'; // ... }
ES5
規(guī)定,函數(shù)只能在頂層作用域和函數(shù)作用域之中聲明,不能在塊級(jí)作用域聲明。
// 情況一 if (true) { function f() {} } // 情況二 try { function f() {} } catch(e) { // ... }
上面兩種函數(shù)聲明,根據(jù) ES5
的規(guī)定都是非法的。
但是,瀏覽器沒有遵守這個(gè)規(guī)定,為了兼容以前的舊代碼,還是支持在塊級(jí)作用域之中聲明函數(shù),因此上面兩種情況實(shí)際都能運(yùn)行,不會(huì)報(bào)錯(cuò)。
ES6
引入了塊級(jí)作用域,明確允許在塊級(jí)作用域之中聲明函數(shù)。ES6
規(guī)定,塊級(jí)作用域之中,函數(shù)聲明語句的行為類似于 let
,在塊級(jí)作用域之外不可引用。
function f() { console.log('I am outside!'); } (function () { if (false) { // 重復(fù)聲明一次函數(shù)f function f() { console.log('I am inside!'); } } f(); }());
上面代碼在 ES5
中運(yùn)行,會(huì)得到“I am inside!
”,因?yàn)樵?if
內(nèi)聲明的函數(shù) f
會(huì)被提升到函數(shù)頭部,實(shí)際運(yùn)行的代碼如下。
// ES5 環(huán)境 function f() { console.log('I am outside!'); } (function () { function f() { console.log('I am inside!'); } if (false) { } f(); }());
ES6
就完全不一樣了,理論上會(huì)得到“I am outside!
”。因?yàn)閴K級(jí)作用域內(nèi)聲明的函數(shù)類似于 let
,對(duì)作用域之外沒有影響。
但是,如果你真的在 ES6
瀏覽器中運(yùn)行一下上面的代碼,是會(huì)報(bào)錯(cuò)的,這是為什么呢?
// 瀏覽器的 ES6 環(huán)境 function f() { console.log('I am outside!'); } (function () { if (false) { // 重復(fù)聲明一次函數(shù)f function f() { console.log('I am inside!'); } } f(); }()); // Uncaught TypeError: f is not a function
上面的代碼在 ES6
瀏覽器中,都會(huì)報(bào)錯(cuò)。
原來,如果改變了塊級(jí)作用域內(nèi)聲明的函數(shù)的處理規(guī)則,顯然會(huì)對(duì)老代碼產(chǎn)生很大影響。為了減輕因此產(chǎn)生的不兼容問題,ES6 規(guī)定,瀏覽器的實(shí)現(xiàn)可以不遵守上面的規(guī)定,有自己的行為方式
允許在塊級(jí)作用域內(nèi)聲明函數(shù)。
函數(shù)聲明類似于var
,即會(huì)提升到全局作用域或函數(shù)作用域的頭部。
同時(shí),函數(shù)聲明還會(huì)提升到所在的塊級(jí)作用域的頭部。
注意,上面三條規(guī)則只對(duì) ES6
的瀏覽器實(shí)現(xiàn)有效,其他環(huán)境的實(shí)現(xiàn)不用遵守,還是將塊級(jí)作用域的函數(shù)聲明當(dāng)作 let
處理。
根據(jù)這三條規(guī)則,瀏覽器的 ES6
環(huán)境中,塊級(jí)作用域內(nèi)聲明的函數(shù),行為類似于 var
聲明的變量。上面的例子實(shí)際運(yùn)行的代碼如下。
// 瀏覽器的 ES6 環(huán)境 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
考慮到環(huán)境導(dǎo)致的行為差異太大,應(yīng)該避免在塊級(jí)作用域內(nèi)聲明函數(shù)。如果確實(shí)需要,也應(yīng)該寫成函數(shù)表達(dá)式,而不是函數(shù)聲明語句。
// 塊級(jí)作用域內(nèi)部的函數(shù)聲明語句,建議不要使用 { let a = 'secret'; function f() { return a; } } // 塊級(jí)作用域內(nèi)部,優(yōu)先使用函數(shù)表達(dá)式 { let a = 'secret'; let f = function () { return a; }; }
如果沒有大括號(hào),JavaScript
引擎就認(rèn)為不存在塊級(jí)作用域。
// 第一種寫法,報(bào)錯(cuò) if (true) let x = 1; // 第二種寫法,不報(bào)錯(cuò) if (true) { let x = 1; }
上面代碼中,第一種寫法沒有大括號(hào),所以不存在塊級(jí)作用域,而let只能出現(xiàn)在當(dāng)前作用域的頂層,所以報(bào)錯(cuò)。第二種寫法有大括號(hào),所以塊級(jí)作用域成立。
函數(shù)聲明也是如此,嚴(yán)格模式下,函數(shù)只能聲明在當(dāng)前作用域的頂層。
// 不報(bào)錯(cuò) 'use strict'; if (true) { function f() {} } // 報(bào)錯(cuò) 'use strict'; if (true) function f() {}
以上就是關(guān)于“ES6塊級(jí)作用域是什么及怎么應(yīng)用”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。