複習小結:函數作用域和區塊的作用域的行為是一樣的,可以認為,任何宣告在某個作用域的變量,都將附屬於這個作用域。
1、現在我們出兩個問題,給出下面兩段程式碼,請先思考輸出的結果,再去實踐一下,相信你會出現疑惑!
//第一段代码 a=2; var a; console.log(a); //第二段代码 console.log(a); var a=2;
2、我猜結果是這樣的:第一段程式碼你猜結果是underfined,然後瀏覽器上執行結果卻是2;第二段程式碼你猜結果是2,但瀏覽器上運行的結果是underfined。兄弟!是不是這樣(即便不是這樣我猜你肯定也是其他形式的錯誤猜測)。
3、我們在解釋為什麼第一段程式碼結果是2,而第二段程式碼的結果是undefined,首先回想之前我們說的一個var a=2的程式碼在JS看來就是兩段程式碼:var a和a=2;前者是在編譯時候進行的後者是在執行時執行的,那麼問題來了?變數和函數的宣告都會都在程式執行前被處理,那麼程式碼的運行順序還是你看到的書寫順序麼?
4、對於第一段程式碼,第二行程式碼var a在編譯的時候率先被處理,第一、三行在運行時被處理,那麼整個程式碼的處裡形式如下:
//第一段代码被JS这样的顺序处理了 var a; a=2; console.log(a);
你看!按照這樣的處理方式你就能看懂了,喔!先聲明在賦值,最後印出來。
5、同樣的道理,第二段程式碼的處理方式是這樣的:
//第二段代码被JS以这样的形式处理: var a; console.log(a); a=2;
在編譯的時候a已經被宣告了,但是在執行的時候,執行到console. log(a)之前a就沒有被賦值,印出來當然是underfined;
6、所以程式碼被JS處理的過程中,變數和函數的宣告在程式碼中的位置好像被移動到了作用域最上面,這個在編譯過程中宣告的優先處理的過程就是提升!
1、來看下面這個程式碼:
foo(); function foo(){ console.log(a); var a=2; }
全域作用域會對foo函數宣告提升,在foo作用域中又會對a進行提升,處理的形式如下:
function foo(){ var a; console.log(a); a=2; } foo();
2、特別注意:函數宣告會被提升,但是函數表達式不會被提升。 具名的函數表達式,名稱標識符在賦值之前也沒有辦法在所在作用域中使用,這兩句話什麼意思?下面兩段程式碼告訴你:
foo(); TypeError bar(); ReferenceError var foo=function bar(){ //.... }
這段程式碼被提升後是這樣的:
var foo; foo(); TypeError bar(); ReferenceError foo=function (){ var bar... //.... }
所以對於foo,有聲明,但是對foo沒有賦值,foo就是undefined,這時對undefined進行操作當然是操作類型的錯誤。而bar,連宣告都沒有,宣告在foo的函數表達式中,所以就是未宣告的錯誤。
3、對於提升來說:函數優先提升,其次是變數;
#相關推薦:
#以上是關於javaScript中作用域和閉包的知識講解的詳細內容。更多資訊請關注PHP中文網其他相關文章!