iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 18
0
Modern Web

【這些年我似是非懂的 Javascript】系列 第 18

【這些年我似是非懂的 Javascript】Day 18 - 拉升(Hoisting)

這篇來分享一下在之前有提過的"提升 (Hoisting)",
就是還被抓到打錯字的這篇 xDD
【這些年我似是非懂的 Javascript】Day 4 - 你一定可以入的了門 #下篇

雖然上面提的那篇已經提過了,
但是我還是再分享一次,

console.log(a); // undefined
var a;

原本 console.log 那行預期應該是 ReferenceError ,卻得到 undefined
why !?
因為 JS 的 Engine 將變數宣告都提升至該範疇的最上面,這種現象就稱為提升( Hositing )

JS 到底是編譯式語言還是直譯式語言

網路上一查一堆都是 JS 是直譯式的,
但是如果他有 Hoisting 那又怎麼可能是直譯式,
再看一次上面的範例,
假使他真的是直譯式語言,
當他執行到第一行的 conosole.log 時就應該要直接噴錯了才不可能會顧慮到下面有一個 var 的宣告。

種種跡象指出,他有經過編譯!
也就是在編譯階段他就把所有的宣告的變數或函式找出來,
並且預先處理好。

函式優先

剛剛上面有提到 JS Engine 會將宣告的變數或函式找出來,
並且預先處理好。
那...誰優先?
答案是函式!
我們來看看下面的範例

foo(); // 函式搶先
var foo; 

function foo(){
    console.log('函式搶先');
}

foo = function foo(){
    console.log('變數優先');
}

如果同樣會提昇的話變數如果較為優先那應該答案會是 "變數優先",但實際結果卻是函式較為優先。

如果沒有 Hoisting

如果 JS 沒有 Hoisting 會造成什麼問題?

  • 必須要先宣告變數才能使用
  • 必須要先宣告函式才能使用
  • 沒辦法達成 function 互相使用

第一點還行,第二點就會滿不方便的,你必須要確保你要呼叫的函式在你使用的上方,那萬一要互相 call ...
就會造成第三點所說的,沒辦法達到 function 互 call。

目前我功力還沒有可以到解釋他是如何運作的,
只能大概描述他會發生並且避免,
如果想知道更詳細的運作方式,
我這邊還是再推一次這位大大寫的,
(雖然我目前還有些看不太懂)
但是寫的超讚,推推!
我知道你懂 hoisting,可是你了解到多深?

以上是今天的內容
感謝您的收看


參考來源:

你所不知道的 JS|範疇與 Closures,this 與物件原型 (You Don't Know JS: this & Object Prototypes))
我知道你懂 hoisting,可是你了解到多深?


上一篇
【這些年我似是非懂的 Javascript】Day 17 - 區塊的範疇
下一篇
# 【這些年我似是非懂的 Javascript】Day 19 - 閉包 (Closure) # Part 1
系列文
【這些年我似是非懂的 Javascript】34

尚未有邦友留言

立即登入留言