為什么允許在JavaScript的If語句中重新聲明變量 [英] Why redeclaring a variable is allowed in an IF statement in JavaScript
本文介紹了為什么允許在JavaScript的If語句中重新聲明變量的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我知道if
語句不像函數那樣有自己的作用域,這意味著它與包含上下文的作用域相同。但如果是這樣,為什么允許我再次重新聲明相同的變量?
var foo = 123;
if (true) {
console.log(foo) // 123
var foo = 456; // Shouldnt it throw an error if refers to same variable?
}
console.log(foo) // 456
推薦答案
我們需要了解編譯器和Java腳本運行時引擎如何處理和執行代碼。
編譯器
讓我們看看編譯器如何看到下面的代碼片段并創建適當的作用域。
1. var foo = 123;
2. if (true) {
3. console.log(foo) // 123
4. var foo = 456;
5. }
6. console.log(foo) // 456
- 第1行上的編譯器在第一次遇到
foo
標識符時將該標識符放入全局作用域。 - 在第2行,它編譯器創建一個塊作用域來保存標識符的引用。
- 第3行是執行上下文,因此編譯器移到下一行。
- 第4行的編譯器看到
foo
標識符,并檢查該標識符是否已存在于全局作用域中(注意:var
沒有塊作用域。因此,它在作用域中向上看一個級別,即全局作用域)。此處全局作用域已具有該標識符,因此它轉到下一行代碼。 - 第6行是執行上下文。
Java(JS)引擎
它使用編譯器創建的作用域分配和執行代碼。
- 第1行運行時在作用域中查找標識符
foo
,因為它賦值為123
- 第2行是真實的,因此它進入了塊。
- 在第3行,它在塊作用域中查找標識符
foo
。由于foo
不存在于塊作用域中,因此它看起來比全局作用域高一個級別。foo
在全局作用域中可用,值為123
。因此console.log(foo)
是123
- 第4行:它在塊作用域中查找標識符
foo
。由于foo
不存在于塊作用域中,因此它看起來比全局作用域高一個級別。foo
在全局作用域中可用,因此它將值456
重新賦值為foo
?,F在foo is 456
。 - 第6行。JS引擎在當前作用域中查找
foo
標識符,當前作用域為全局作用域。foo
在全局作用域中可用,值為456
。
現在,讓我們看看問題
為什么允許在JavaScript的If語句中重新聲明變量?
var foo = 456;
看起來像是重新聲明,但實際上并非如此。它使用相同的全局聲明的標識符。
在某些情況下,出于readability
的目的最好使用這種模式。
function test() {
var siteId;
if(condition) {
// more code 100+ lines
siteId = getId();
} else {
var siteId = 1001; // redeclaring here we are communicating the reader for sure we have the `siteId`
}
// other code
}
這篇關于為什么允許在JavaScript的If語句中重新聲明變量的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持IT屋!
查看全文