天天看點

詳細分析ES6中let與var變量提升的差別

今天在知乎看到一篇講解let跟var的文章,我認為關于let不會變量提升問題存疑,于是乎想自己寫一篇文章結合理論實踐給各位更清晰的差別開let跟var的變量提升問題。(觀點基于我的實踐,如有錯還請大佬們指點,純屬探讨)

let跟var 大部分人的第一反應肯定作用域問題,var沒有塊級作用域,而let擁有塊級作用域。這個也是我們最熟悉的一個特性,其實它們對于變量提升的處理也是不一樣的。

先導知識:每個function都有自己的作用域

了解:下面結合我在牛客網刷過的一道題來分析變量提升以及作用域問題:

詳細分析ES6中let與var變量提升的差別

從上至下分析,先從頂級作用域裡定義了a跟b,這裡考察的點我認為在于function内部的語句:var a=b=3;這裡實際可以拆分為:b = 3;var a = b;是以b是一個全局變量。因為變量提升的問題,是以我将整個函數重寫一遍讓你們更直覺的看到實際的函數:

詳細分析ES6中let與var變量提升的差別

以從上至下alert的分别為: undefined,undefined,3,3,undefined,3

好,作用域大緻了解了,下面講一下老生常談的變量提升問題了,從作用域的例子裡我們已經在函數内部看到了變量提升了,衆所周知js變量是會提升的,是以今天看到說let不會變量提升後我就特意去測試了一下,一眼看下去好像沒什麼錯誤,他給出的例子大概是:

詳細分析ES6中let與var變量提升的差別

但是我認為導緻出錯的原因是let 定義僅僅提升變量,而不會自動指派undefined

先說在我的觀點中為什麼先用後let會報錯而先用後var不會報錯:

var 定義變量提升的同時會直接指派一個undefined,而let定義變量是單純的declare,不賦任何值。再往上翻看一眼我給你們寫的變量提升的圖檔裡就var的定義同時指派了undefined。

将上面的題稍微改變一下,換成let會怎麼樣?這裡我将alert改成console.log 在浏覽器示範一遍,清晰直覺

詳細分析ES6中let與var變量提升的差別

先說效果:報錯

詳細分析ES6中let與var變量提升的差別

報了一個 a is not defined 的錯,為什麼會這樣呢?同樣的我将這段代碼改寫為提升後的版本:

詳細分析ES6中let與var變量提升的差別

這裡我想表達的意思是,let定義就單純隻是定義,不會自動賦上undefined,隻有當js執行到let指派語句那裡才會替變量指派undefined

如果結論是let變量不會提升的話,原函數是不應該這麼早報錯的,因為他在目前作用域上找不到a就會順着作用域鍊找到最外層的a,那麼在函數内的最想列印出的a是已指派的,是以會列印3才對

是以得出結論:let 定義變量也會提升,但是不會自動指派一個undefined,而var定義變量的同時會自動指派undefined。

用代碼描述就是

詳細分析ES6中let與var變量提升的差別

轉化為

詳細分析ES6中let與var變量提升的差別
詳細分析ES6中let與var變量提升的差別

轉化為

詳細分析ES6中let與var變量提升的差別