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