1. 程式人生 > >JS函式宣告與函式表示式的區別

JS函式宣告與函式表示式的區別

函式宣告與函式表示式的區別

前面我們已經說了兩種定義函式的方式:函式宣告與函式表示式。那麼這兩種方式有區別嗎,還是一樣的呢?下面我們來進一步探討探討。

下面我們定義了兩個函式分別為 hello 和 hi,前者採用函式宣告,後者採用函式表示式,然後再呼叫,如下:

function hello () {
    console.log('Hello the world');
}

var hi = function () {
    console.log('Hi, IMWeb');
}

hello(); // 'Hello the world'
hi(); // 'Hi, IMWeb'

上面的呼叫,我們都能得到正確的執行,並沒有什麼區別。但是如果我們把順序掉下,先呼叫函式後定義函式,那麼情況就會有點不一樣了。如下:

hello(); // 'Hello the world'
hi(); // Uncaught TypeError: hi is not a function

function hello () {
    console.log('Hello the world');
}

var hi = function () {
    console.log('Hi, IMWeb');
}

從上我們可以看到,hello 函式可以照常執行,但是我們的 hi 函式就會報錯了。根據報錯“Uncaught TypeError: hi is not a function”,我們知道 hi 不是 function 了,那又是什麼呢?我們繼續使用 typeof

 檢視下:

console.log(typeof hello); // function
console.log(typeof hi); // undefined

function hello () {
    console.log('Hello the world');
}

var hi = function () {
    console.log('Hi, IMWeb');
}
function hello () {
    console.log('Hello the world');
}
var hi;

console.log(typeof hello); // function
console.log(typeof hi); // undefined

hi = function () {
    console.log('Hi, IMWeb');
}

通過 typeof 我們可以看到 hi 現在是個 undefined 了,這是為什麼呢?

這是因為 JavaScript 直譯器中存在一種變數宣告被提升(hoisting)的機制,也就是說變數(函式)的宣告會被提升到當前作用域的最前面,即使寫程式碼的時候是寫在最後面,也還是會被提升至最前面。

這樣上面的例子在執行的時候就成了這樣的:

這樣是不是一下就恍然大悟了。所以在實際開發的時候,一定要注意變數(函式)的宣告會被提升到當前作用域的最前面

本文章轉載於IMWeb