首頁 >web前端 >js教程 >JavaScript提升 - 移動和停留什麼

JavaScript提升 - 移動和停留什麼

DDD
DDD原創
2025-01-30 08:30:10369瀏覽

Javascript Hoisting - What Moves and What Stays

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存在,但它還沒有被賦值。

letconst 的暫時性死區 (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

這也包括使用letconst聲明的任何內容,當然也包括函數。

暫時性死區 (TDZ)

說到暫時性死區,這是letconst聲明在初始化之前存在的地方。與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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn