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
這樣上面的例子在執行的時候就成了這樣的:
作用域
這樣是否是一下就恍然大悟了。因此在實際開發的時候,必定要注意變量(函數)的聲明會被提高到當前做用域的最前面開發