接着上一篇講<JavaScript Scoping & Hoisting>javascript
Javascript是一門容易遭人誤解的語言,可是它的強大毋庸置疑。我的以爲,要想深刻理解Javascript語言,首先必須對其基本的概念(例如:Scope,Closure,Hoisting等)要真正理解。今天想經過本身的理解來對Javascript Hoisting(國內通常翻譯爲 變量提高)作一個闡述:java
在解釋Javascript Hoisting以前,先看一下幾段代碼:函數
//代碼段1-------------------------- var myvar = '變量值'; console.log(myvar); // 變量值 //代碼段2-------------------------- var myvar = '變量值'; (function() { console.log(myvar); //變量值 })(); //代碼段3---------------------------- var myvar = '變量值'; (function() { console.log(myvar); // undefined var myvar = '內部變量值'; })();
代碼段1會在控制檯打印出 變量值 ,很容易理解;代碼段2也會在控制檯打印出 變量值 ,Javascript編譯器首先在匿名函數內部做用域(Scope)查看變量myvar是否聲明,發現沒有,就繼續向上一級的做用域(Scope)查看是否聲明 myvar,發現存在,即打印出該做用域的myvar值。但代碼段3只是對代碼段2作一個微調,結果卻輸出了undefine!!!測試
在理解代碼段3以前,必須先理解Javascript Hoisting的概念。Javascript Hoisting:In javascript, every variable declaration is hoisted to the top of its declaration context.個人理解就是在Javascript語言中,變量的聲明(注意不包含變量初始化)會被提高(置頂)到聲明所在的上下文,也就是說,在變量的做用域內,無論變量在何處聲明,都會被提高到做用域的頂部,可是變量初始化的順序不變。.net
下圖的左邊和右邊的代碼輸出結構是同樣的,左邊的代碼段在JS執行時,實際的執行順序如右邊的代碼所示(JS編譯器會將變量聲明進行提高處理)。翻譯
理解了提高的概念以後,再回到開頭的代碼段3的理解中來,代碼段3和在被Hositing以後的代碼以下圖所示:code
兩者輸出的結構都爲undefined!可理解爲內部變量myvar在匿名函數的內最後一行進行變量聲明並賦值,可是JS解釋器會將變量聲明(不包含賦值)提高(Hositing)到匿名函數的第一行(頂部),因爲只是聲明myvar變量,在執行console.log(myvar)語句時,並未對myvar進行賦值,因此JS輸出undefined。blog
若是變量聲明未提高(Hositing)置頂,則應該會報錯誤。以下圖所示:ip
下面給個測試題,來看看你對Hositing的概念是否理解作用域
//測試代碼---------------------- var myvar = '變量值'; (function() { console.log(myvar); // ? myvar = '內部變量值'; })();
該代碼段應該輸出什麼值呢?