函數聲明與函數表達式的區別

JS有兩種定義函數的方式:函數聲明與函數表達式。那麼這兩種方式有區別嗎,仍是同樣的呢?下面咱們來進一步探討探討。函數

下面咱們定義了兩個函數分別爲 hello 和 hi,前者採用函數聲明,後者採用函數表達式,而後再調用,以下:spa

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

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

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

上面的調用,咱們都能獲得正確的運行,並無什麼區別。可是若是咱們把順序掉下,先調用函數後定義函數,那麼狀況就會有點不同了。以下:code

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 查看下:blog

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)的機制,也就是說變量(函數)的聲明會被提高到當前做用域的最前面,即便寫代碼的時候是寫在最後面,也仍是會被提高至最前面。ip

這樣上面的例子在執行的時候就成了這樣的:
圖片描述作用域

這樣是否是一下就恍然大悟了。因此在實際開發的時候,必定要注意變量(函數)的聲明會被提高到當前做用域的最前面開發

相關文章
相關標籤/搜索