JavaScript的提昇機制就像舞台劇的佈景準備。在代碼運行之前(在“創建階段”),JavaScript會將所有聲明提升到其作用域的頂部,就像舞台工作人員在幕布升起前將道具搬到指定位置一樣。唯一的區別是,只有聲明被提升,初始化並沒有被提升。
根據ECMAScript規範,這種行為實際上是JavaScript在創建階段創建所謂的“詞法環境”的一部分。但讓我們不要過於技術化,只需記住JavaScript會在運行代碼之前對其進行“預掃描”。
var
提升<code class="language-javascript">console.log(x); // 输出:undefined var x = 5; console.log(x); // 输出:5</code>
在這個例子中,var x
聲明被提升到作用域的頂部,但初始化x = 5
沒有被提升。這就是為什麼第一個console.log(x)
輸出undefined
而不是拋出錯誤。變量x
存在,但它還沒有被賦值。
let
和 const
的暫時性死區 (TDZ)<code class="language-javascript">console.log(y); // 抛出ReferenceError: Cannot access 'y' before initialization let y = 10; console.log(y); // 输出:10</code>
在這個例子中,let y
聲明被提升,但是它在初始化行之前位於暫時性死區 (TDZ)。在初始化之前嘗試訪問y
會導致ReferenceError
。此行為與var
不同,var
在類似情況下只會返回undefined
。
這也包括使用
let
或const
聲明的任何內容,當然也包括函數。
說到暫時性死區,這是let
和const
聲明在初始化之前存在的地方。與var
在初始化之前訪問時返回undefined
不同,這些現代聲明會拋出錯誤。 ECMAScript規範將此行為稱為“暫時性死區語義”,但我稱之為“JavaScript讓我們誠實”。
<code class="language-javascript">function setupEventHandler() { handleClick(); // 可运行! const config = { debug: true, }; function handleClick() { if (config?.debug) { // 未定义! console.log("Debug mode"); } } } setupEventHandler();</code>
看到這裡發生了什麼嗎?函數聲明handleClick
被提升了,所以我們可以提前調用它。但是config
對象呢?它仍然留在它所在的位置。這就是為什麼在handleClick
內部訪問config
會給我們undefined
,我們試圖在腳本準備好之前讀取它。
類提升的工作方式不太一樣。
<code class="language-javascript">const dog = new Animal(); // 抛出错误! class Animal { constructor() { this.type = "mammal"; } }</code>
雖然類被提升了,但在它們的定義被評估之前,它們仍然處於“暫時性死區”。這意味著在聲明它們之前,你無法訪問它們。
記住,聲明被移動到頂部,但初始化保持不變。
以上是JavaScript提升 - 移動和停留什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!