」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 了解 JavaScript 中的提升:綜合指南

了解 JavaScript 中的提升:綜合指南

發佈於2024-11-05
瀏覽:136

Understanding Hoisting in JavaScript: A Comprehensive Guide

JavaScript 中的提升

提升是一種行為,其中變數和函數聲明在先前被移動(或「提升」)到其包含範圍(全域範圍或函數範圍)的頂部程式碼被執行。這意味著您可以在程式碼中實際聲明變數和函數之前使用它們。

變數提升

變數

  • 用 var 宣告的變數被提升到其作用域的頂部,但它們的值直到程式碼中發生賦值的點才被初始化。
console.log(x); // undefined
var x = 5;
console.log(x); // 5

讓和常數

  • 用 let 和 const 宣告的變數也會被提升,但會被放置在「臨時死區」中,直到到達它們的宣告為止。在聲明之前訪問它們將導致引用錯誤。
console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 10;

// block scope
{
  let x = 5;
}

console.log(x); // ReferenceError: x is not defined

函數提升

傳統功能

  • 函數宣告被完全提升,這意味著宣告和函數體都被移動到作用域的頂端。這允許您在程式碼中聲明函數之前調用該函數。
sayHello(); // "Hello!"
function sayHello() {
  console.log("Hello!");
}
  • 相反,函數表達式(其中將函數分配給變數)僅作為變數提升,因此在初始化變數之前調用它們將導致未定義或類型錯誤。
greet(); // TypeError: greet is not a function
var greet = function () {
  console.log("Hi!");
};

greet(); // ReferenceError: Cannot access 'one' before initialization
let greet = function () {
  console.log("Hi!");
};

箭頭功能

  • 相反,函數表達式(其中將函數分配給變數)僅作為變數提升,因此在初始化變數之前調用它們將導致未定義或類型錯誤。
greet(); // TypeError: greet is not a function
var greet = () => {
  console.log("Hi!");
};

greet(); // ReferenceError: Cannot access 'one' before initialization
let greet = function () {
  console.log("Hi!");
};

暫時死區 (TDZ)

臨時死區 (TDZ) 對於使用 let 和 const 宣告的變數存在,因為 JavaScript 旨在防止您在宣告和初始化這些變數之前存取它們。

為什麼 var 和 let、const 在提升中表現不同

  • 這是因為JavaScript的歷史演變。
  • 最初,JavaScript 是為非開發人員的使用者設計的,JavaScript 的主要核心用途是為網頁添加小型互動元素。
  • 所以 var 只支援函數作用域。同樣在那個時候,還沒有塊作用域。
  • 但在 JavaScript 的後期發展中,使用 var 和修復 bug 變得更加複雜。
  • 因此,為了讓 JavaScript 與其他現代語言競爭,增加了更多功能,如 let、const、箭頭函數、ES6 方法等。

為什麼 var 不像 let 和 const 那樣更新

  • 這是因為向後相容。
  • 當時,JavaScript已被許多企業廣泛使用,因此更新或變更現有功能會導致程式碼庫的破壞。
  • 因此,單獨添加了現代功能。

常見面試問題

  • JavaScript 中什麼是提升?
  • JavaScript 中什麼是提升的,什麼不是?
  • var、let 和 const 在提升方面有什麼不同?
  • JavaScript 中的臨時死區 (TDZ) 是什麼?
  • 您能解釋一下使用函數宣告與函數表達式進行提升嗎?
  • ES6模組中的提升是什麼?
  • 為什麼我們應該避免在現實程式碼中依賴提升?

概括

  • 提升是 JavaScript 中的預設行為,其中變數和函數宣告在編譯階段被移到各自作用域的頂部。
  • 提升僅適用於使用 var 和傳統函數宣告的變量,不適用於 let、const 和箭頭函數。
  • 只有函數聲明被提升,所以傳統函數可以工作,但如果函數被分配給變量,則在定義之前它是不可調用的。
  • 之所以var和傳統函數被提升,而let、const和箭頭函數沒有被提升,是因為在初期,JavaScript主要用於小型UI交互。
  • 但後來,隨著 JavaScript 被廣泛用於企業建立應用程序,僅在全局範圍內修復錯誤變得更加困難。
  • 因此,在未來的更新中,會解決更多安全性問題。
  • 此外,更新現有功能會破壞程式碼庫,因此單獨新增功能。
版本聲明 本文轉載於:https://dev.to/nishanthank/understanding-hoisting-in-javascript-a-comprehensive-guide-5bic?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何檢查對像是否具有Python中的特定屬性?
    如何檢查對像是否具有Python中的特定屬性?
    方法來確定對象屬性存在尋求一種方法來驗證對像中特定屬性的存在。考慮以下示例,其中嘗試訪問不確定屬性會引起錯誤: >>> a = someClass() >>> A.property Trackback(最近的最新電話): 文件“ ”,第1行, AttributeError: SomeClass...
    程式設計 發佈於2025-06-09
  • Android如何向PHP服務器發送POST數據?
    Android如何向PHP服務器發送POST數據?
    在android apache httpclient(已棄用) httpclient httpclient = new defaulthttpclient(); httppost httppost = new httppost(“ http://www.yoursite.com/script.p...
    程式設計 發佈於2025-06-09
  • 為什麼儘管有效代碼,為什麼在PHP中捕獲輸入?
    為什麼儘管有效代碼,為什麼在PHP中捕獲輸入?
    在php ;?>" method="post">The intention is to capture the input from the text box and display it when the submit button is clicked.但是,輸出...
    程式設計 發佈於2025-06-09
  • 如何使用替換指令在GO MOD中解析模塊路徑差異?
    如何使用替換指令在GO MOD中解析模塊路徑差異?
    在使用GO MOD時,在GO MOD 中克服模塊路徑差異時,可能會遇到衝突,其中3個Party Package將另一個PAXPANCE帶有導入式套件之間的另一個軟件包,並在導入式套件之間導入另一個軟件包。如迴聲消息所證明的那樣: go.etcd.io/bbolt [&&&&&&&&&&&&&&&&...
    程式設計 發佈於2025-06-09
  • 為什麼PYTZ最初顯示出意外的時區偏移?
    為什麼PYTZ最初顯示出意外的時區偏移?
    與pytz 最初從pytz獲得特定的偏移。例如,亞洲/hong_kong最初顯示一個七個小時37分鐘的偏移: 差異源利用本地化將時區分配給日期,使用了適當的時區名稱和偏移量。但是,直接使用DateTime構造器分配時區不允許進行正確的調整。 example pytz.timezone(&#...
    程式設計 發佈於2025-06-09
  • Java的Map.Entry和SimpleEntry如何簡化鍵值對管理?
    Java的Map.Entry和SimpleEntry如何簡化鍵值對管理?
    的綜合集合:在Java中介紹Java的Map.entry和SimpleEntry和SimpleEntry和SimpleEntry和SimpleEntry和SimpleEntry和SimpleEntry和SimpleEntry和SimpleEntry apry and Map。 地圖。它具有兩個通用...
    程式設計 發佈於2025-06-09
  • 如何使用FormData()處理多個文件上傳?
    如何使用FormData()處理多個文件上傳?
    )處理多個文件輸入時,通常需要處理多個文件上傳時,通常是必要的。 The fd.append("fileToUpload[]", files[x]); method can be used for this purpose, allowing you to send multi...
    程式設計 發佈於2025-06-09
  • Go語言垃圾回收如何處理切片內存?
    Go語言垃圾回收如何處理切片內存?
    Garbage Collection in Go Slices: A Detailed AnalysisIn Go, a slice is a dynamic array that references an underlying array.使用切片時,了解垃圾收集行為至關重要,以避免潛在的內存洩...
    程式設計 發佈於2025-06-09
  • 對象擬合:IE和Edge中的封面失敗,如何修復?
    對象擬合:IE和Edge中的封面失敗,如何修復?
    To resolve this issue, we employ a clever CSS solution that solves the problem:position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%)...
    程式設計 發佈於2025-06-09
  • Java中假喚醒真的會發生嗎?
    Java中假喚醒真的會發生嗎?
    在Java中的浪費喚醒:真實性或神話? 在Java同步中偽裝喚醒的概念已經是討論的主題。儘管存在這種行為的潛力,但問題仍然存在:它們實際上是在實踐中發生的嗎? Linux的喚醒機制根據Wikipedia關於偽造喚醒的文章,linux實現了pthread_cond_wait()功能的Linux實現,...
    程式設計 發佈於2025-06-09
  • 如何使用Python的請求和假用戶代理繞過網站塊?
    如何使用Python的請求和假用戶代理繞過網站塊?
    如何使用Python的請求模擬瀏覽器行為,以及偽造的用戶代理提供了一個用戶 - 代理標頭一個有效方法是提供有效的用戶式header,以提供有效的用戶 - 設置,該標題可以通過browser和Acterner Systems the equestersystermery和操作系統。通過模仿像Chro...
    程式設計 發佈於2025-06-09
  • Spark DataFrame添加常量列的妙招
    Spark DataFrame添加常量列的妙招
    在Spark Dataframe ,將常數列添加到Spark DataFrame,該列具有適用於所有行的任意值的Spark DataFrame,可以通過多種方式實現。使用文字值(SPARK 1.3)在嘗試提供直接值時,用於此問題時,旨在為此目的的column方法可能會導致錯誤。 df.withCo...
    程式設計 發佈於2025-06-09
  • 如何正確使用與PDO參數的查詢一樣?
    如何正確使用與PDO參數的查詢一樣?
    在pdo 中使用類似QUERIES在PDO中的Queries時,您可能會遇到類似疑問中描述的問題:此查詢也可能不會返回結果,即使$ var1和$ var2包含有效的搜索詞。錯誤在於不正確包含%符號。 通過將變量包含在$ params數組中的%符號中,您確保將%字符正確替換到查詢中。沒有此修改,PD...
    程式設計 發佈於2025-06-09
  • 為什麼我的CSS背景圖像出現?
    為什麼我的CSS背景圖像出現?
    故障排除:CSS背景圖像未出現 ,您的背景圖像儘管遵循教程說明,但您的背景圖像仍未加載。圖像和样式表位於相同的目錄中,但背景仍然是空白的白色帆布。 而不是不棄用的,您已經使用了CSS樣式: bockent {背景:封閉圖像文件名:背景圖:url(nickcage.jpg); 如果您的html,cs...
    程式設計 發佈於2025-06-09
  • 如何在Java字符串中有效替換多個子字符串?
    如何在Java字符串中有效替換多個子字符串?
    在java 中有效地替換多個substring,需要在需要替換一個字符串中的多個substring的情況下,很容易求助於重複應用字符串的刺激力量。 However, this can be inefficient for large strings or when working with nu...
    程式設計 發佈於2025-06-09

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3