今天在知乎看到一篇講解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。

用代碼描述就是:

轉化為:

轉化為:


推薦閱讀:
查看原文 >>
相關文章