詳細分析ES6中let與var變數提升的區別
今天在知乎看到一篇講解let跟var的文章,我認為關於let不會變數提升問題存疑,於是乎想自己寫一篇文章結合理論實踐給各位更清晰的區別開let跟var的變數提升問題。(觀點基於我的實踐,如有錯還請大佬們指點,純屬探討)
let跟var 大部分人的第一反應肯定作用域問題,var沒有塊級作用域,而let擁有塊級作用域。這個也是我們最熟悉的一個特性,其實它們對於變數提升的處理也是不一樣的。
先導知識:每個function都有自己的作用域
理解:下面結合我在牛客網刷過的一道題來分析變數提升以及作用域問題:
從上至下分析,先從頂級作用域裡定義了a跟b,這裡考察的點我認為在於function內部的語句:var a=b=3;這裡實際可以拆分為:b = 3;var a = b;所以b是一個全域性變數。因為變數提升的問題,所以我將整個函式重寫一遍讓你們更直觀的看到實際的函式:
以從上至下alert的分別為: undefined,undefined,3,3,undefined,3
好,作用域大致理解了,下面講一下老生常談的變數提升問題了,從作用域的例子裡我們已經在函式內部看到了變數提升了,眾所周知js變數是會提升的,所以今天看到說let不會變數提升後我就特意去測試了一下,一眼看下去好像沒什麼錯誤,他給出的例子大概是:
但是我認為導致出錯的原因是let 定義僅僅提升變數,而不會自動賦值undefined
先說在我的觀點中為什麼先用後let會報錯而先用後var不會報錯:
var 定義變數提升的同時會直接賦值一個undefined,而let定義變數是單純的declare,不賦任何值。再往上翻看一眼我給你們寫的變數提升的圖片裡就var的定義同時賦值了undefined。
將上面的題稍微改變一下,換成let會怎麼樣?這裡我將alert改成console.log 在瀏覽器演示一遍,清晰直觀
先說效果:報錯
報了一個 a is not defined 的錯,為什麼會這樣呢?同樣的我將這段程式碼改寫為提升後的版本:
這裡我想表達的意思是,let定義就單純只是定義,不會自動賦上undefined,只有當js執行到let賦值語句那裡才會替變數賦值undefined
如果結論是let變數不會提升的話,原函式是不應該這麼早報錯的,因為他在當前作用域上找不到a就會順著作用域鏈找到最外層的a,那麼在函式內的最想打印出的a是已賦值的,所以會列印3才對
所以得出結論:let 定義變數也會提升,但是不會自動賦值一個undefined,而var定義變數的同時會自動賦值undefined。
用程式碼描述就是
轉化為
轉化為