摘要:最近在代碼中不小心不規(guī)范的,在里面定義了塊級變量,導(dǎo)致頁面在某些瀏覽器中出錯,本文討論以下語句中的塊級作用域。而與無關(guān)每一個并不會構(gòu)成一個獨立的塊級作用域。
??最近在代碼中不小心不規(guī)范的,在switch里面定義了塊級變量,導(dǎo)致頁面在某些瀏覽器中出錯,本文討論以下switch語句中的塊級作用域。
switch語句中的塊級作用域
switch語句中的塊級作用域可能存在的問題
規(guī)范和檢測
本文的原文在我的博客中,https://github.com/forthealll...
歡迎star
一、switch語句中的塊級作用域??ES6 或 TS 引入了塊級作用域,通過let和const、class等可以定義塊級作用域里的變量,塊級作用域內(nèi)的變量不存在變量提升,且存在暫時性死區(qū)。常見的if語句,for循環(huán)的循環(huán)體內(nèi)都可以定義塊級變量。那么switch語句中的塊級作用域是什么呢? 先給出結(jié)論:
switch語句中的塊級作用域,在整個switch語句中,而不是對于每一個case生成一個獨立的塊級作用域。
下面來舉幾個例子來說明這個問題:
let number = 1; switch(number){ case 1: let name = "Jony"; default: console.log(name) }
上述的代碼會輸出jony。
再看一個例子:
let number = 1; switch(number){ case 1: let name = "Jony"; break; case 2: let name = "yu"; break; default: console.log(name); }
這樣會在重復(fù)生命的錯誤:
Uncaught SyntaxError: Identifier "name" has already been declared
上述兩個例子說明確實switch語句中,整個switch語句構(gòu)成一個塊級作用域。而與case無關(guān),每一個case并不會構(gòu)成一個獨立的塊級作用域。
二、switch語句中的塊級作用域可能存在的問題??我們知道了switch語句,整個switch語句的頂層是一個塊級作用域,但是還要注意case的特殊性,在case中聲明的變量,并不會提升到塊級作用域中。
let number = 2; switch(number){ case 2: name = "yu"; break; }
在這個例子中,name雖然沒有聲明,但是給name賦值相當(dāng)于給全局的window對象復(fù)制,也就是window.name = "yu"。不會有任何問題。
有意思的問題來了:
let number = 2; switch(number){ case 1: let name = "jony"; break; case 2: name = "yu"; break; }
這個例子中,會報錯,會報name未定義的錯誤。
Uncaught ReferenceError: name is not defined
原因的話,這里雖然case里面定義的塊級雖然不會存在變量提升,但是會存在暫時性死區(qū),也就是說如果let name = "jony" 沒有執(zhí)行,也就是name定義的過程沒有執(zhí)行,那么name在整個塊級作用域內(nèi)都是不可用的,都是undefined。
為了證明我們的想法,接著改寫上面的例子:
let number = 1; switch(number){ case 1: let name = "jony"; break; case 2: name = "yu"; break; }
我們把number改成1,我們發(fā)現(xiàn)代碼不會報任何的錯誤,因為此時let name的定義和賦值都被執(zhí)行了。
三、規(guī)范和檢測 一、什么時候會出現(xiàn)問題??可能會說為什么在自己的項目中,在ES6或者TS代碼中即使有上述的錯誤使用,也沒有報錯?
??筆者之前也有這樣的問題,要明確的是是否你把ES6或者TS的代碼直接轉(zhuǎn)化成了es5,然后再調(diào)試或者發(fā)布的線上的,當(dāng)let被編譯成es5后,當(dāng)然就不會存在上述switch中作用域的問題。但是現(xiàn)實中,編譯成es5后的js文件可能太大,對于高版本瀏覽器我們希望直接使用ES6代碼(通過type = module來判斷瀏覽器對于ES6的支持性),那么這么上述問題就會出現(xiàn)。
二、如何檢測和規(guī)避??那么如何避免這種情況呢,當(dāng)然最好的方式,就是不要在case中定義塊級變量,但是萬一不小心寫了上述的問題代碼如何檢測呢。
首先使用typescript,靜態(tài)編譯是不能出現(xiàn)錯誤提示的,因為這個錯誤是運行時異常。最好的方式是通過編寫eslint的規(guī)范來解決上述的非法使用問題。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/53770.html
摘要:最近在代碼中不小心不規(guī)范的,在里面定義了塊級變量,導(dǎo)致頁面在某些瀏覽器中出錯,本文討論以下語句中的塊級作用域。而與無關(guān)每一個并不會構(gòu)成一個獨立的塊級作用域。 ??最近在代碼中不小心不規(guī)范的,在switch里面定義了塊級變量,導(dǎo)致頁面在某些瀏覽器中出錯,本文討論以下switch語句中的塊級作用域。 switch語句中的塊級作用域 switch語句中的塊級作用域可能存在的問題 規(guī)范和檢...
摘要:全局作用域局部作用域局部作用域全局作用域局部作用域塊語句沒有塊級作用域塊級聲明包括和,以及和循環(huán),和函數(shù)不同,它們不會創(chuàng)建新的作用域。局部作用域只在該函數(shù)調(diào)用執(zhí)行期間存在。 一、什么是作用域? 作用域是你的代碼在運行時,各個變量、函數(shù)和對象的可訪問性。(可產(chǎn)生作用的區(qū)域) 二、JavaScript中的作用域 在 JavaScript 中有兩種作用域 全局作用域 局部作用域 當(dāng)變量定...
摘要:解決這個問題的另一種方法是使用閉包。瀏覽器的主要組件包括調(diào)用堆棧,事件循環(huán),任務(wù)隊列和。由于調(diào)用堆棧是空的,事件循環(huán)將選擇回調(diào)并將其推入調(diào)用堆棧進行處理。進程再次重復(fù),堆棧不會溢出。 為了保證的可讀性,本文采用意譯而非直譯。 JavaScript 是一種有趣的語言,我們都喜歡它,因為它的性質(zhì)。瀏覽器是JavaScript的主要運行的地方,兩者在我們的服務(wù)中協(xié)同工作。JS有一些概念,人們...
摘要:解決這個問題的另一種方法是使用閉包。瀏覽器的主要組件包括調(diào)用堆棧,事件循環(huán),任務(wù)隊列和。由于調(diào)用堆棧是空的,事件循環(huán)將選擇回調(diào)并將其推入調(diào)用堆棧進行處理。進程再次重復(fù),堆棧不會溢出。 為了保證的可讀性,本文采用意譯而非直譯。 JavaScript 是一種有趣的語言,我們都喜歡它,因為它的性質(zhì)。瀏覽器是JavaScript的主要運行的地方,兩者在我們的服務(wù)中協(xié)同工作。JS有一些概念,人們...
閱讀 1756·2021-11-24 09:39
閱讀 1686·2021-11-22 15:22
閱讀 1002·2021-09-27 13:36
閱讀 3230·2021-09-24 10:34
閱讀 3329·2021-07-26 23:38
閱讀 2633·2019-08-29 16:44
閱讀 974·2019-08-29 16:39
閱讀 1104·2019-08-29 16:20