輕鬆學習 JavaScript——第 5 部分:簡化函式提升

2017-11-16    分類:WEB開發、程式設計開發、首頁精華0人評論發表於2017-11-16

本文由碼農網 – 小峰原創翻譯,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃

為了理解函式提升,讓我們從以下程式碼開啟我們的學習之旅:

console.log(foo);
var foo = 9;

應該輸出什麼呢?

在任何其他程式語言中,這裡的輸出將會是reference error。但是,在JavaScript中,你將得到undefined作為輸出。為什麼?因為JavaScript會提升變數到執行上下文的頂部。執行上下文可以是宣告變數的函式,也可以是宣告變數的JavaScript檔案。所以,讓我們用函式重寫上面的程式碼片段:

function abc() {
    console.log(foo);
    var foo = 9;
}
abc();

這裡,變數“foo”提升到函式abc執行上下文的頂部;這意味著你可以在宣告之前訪問foo。簡而言之,無論何時你宣告一個變數,JavaScript直譯器都可以將其分成兩個語句:

  • 宣告一個變數。
  • 賦值。

變數的宣告位於執行上下文的頂部,而賦值發生在建立變數的位置。所以上面的程式碼片段被分解成兩個語句,如下圖所示:

變數foo被提升到函式abc的執行上下文的頂部,因此當你在宣告之前使用它時,你會得到“undefined”作為輸出。

請記住,使用let語句宣告的變數不會被提升到執行上下文的頂部。

現在你知道JavaScript中的變數是如何被提升的了,接下來讓我們來探討JavaScript中的函式提升。在JavaScript中,可以通過兩種方式來建立函式:

  • 作為宣告而建立的函式。
  • 作為表示式而建立的函式。

作為宣告或語句建立的函式作為一個整體提升到執行上下文的頂部。但是,作為表示式建立的函式會像變數一樣提升。

為了說明這一點,讓我們建立一個作為語句的函式:

foo();
function foo() {
    console.log("hello");
}

在上面的程式碼中,如果你在函式建立之前使用函式,那麼你會得到hello的輸出。發生這種情況的原因是,作為語句建立的函式會當作一個整體被提升到執行上下文的頂部。

無論何時建立作為語句的函式,都可以在函式建立之前使用該函式。因此,如果你在第5行建立作為語句的函式,那麼你可以在第1-4行中使用該函式,因為函式語句會隨函式主體一起提升到執行上下文的頂部。

函式語句會隨函式主體一起提升到執行上下文的頂部。

函式表示式會像一個變數一樣被提升到執行上下文的頂部。請看下面的程式碼:

foo();
var foo = function () {
    console.log("hello");
}

你正在程式碼中建立函式foo作為表示式,所以JavaScript會像普通變數一樣提升它。 JavaScript會像下圖所示那樣處理上面的程式碼:

正如你在上面的圖片中看到的那樣,foo在執行上下文的頂部被宣告為一個變數,然而,在變數foo中的函式賦值發生在第6行,也就是建立作為表示式函式的地方。所以,當你嘗試執行上面的程式碼時,你會得到錯誤undefined is not a function,如下圖所示:

因此,你不能在函式表示式被建立之前使用函式表示式,因為只有函式宣告會提升到頂部。

綜上所述:

  • 函式語句隨函式主體一起被提升到執行上下文的頂部。你可以在函式建立之前使用作為語句建立的函式。
  • 函式表示式在建立之前不能使用。只有宣告部分會被提升,賦值發生在建立函式的那一行。

在“輕鬆學習JavaScript”系列的下一篇文章中,我們將介紹JavaScript中更為重要的概念,敬請期待。

系列目錄

輕鬆學習 JavaScript——第 1 部分:瞭解 let 語句

輕鬆學習 JavaScript——第 2 部分:函式中的 Rest 引數

輕鬆學習 JavaScript——第 3 部分:函式中的預設引數

輕鬆學習 JavaScript——第 4 部分:函式中的 arguments 物件

輕鬆學習 JavaScript——第 5 部分:簡化函式提升

輕鬆學習 JavaScript——第 6 部分:JavaScript 箭頭函式

輕鬆學習 JavaScript——第 7 部分:物件屬性描述符

輕鬆學習 JavaScript——第 8 部分:JavaScript 中的類

譯文連結:http://www.codeceo.com/article/easy-javascript-05-hoisting.html
英文原文:Easy JavaScript Part 5: Simplifying Function Hoisting
翻譯作者:碼農網 – 小峰
轉載必須在正文中標註並保留原文連結、譯文連結和譯者等資訊。]

相關文章