前端 -- JS變數提升

不要情緒發表於2020-02-07

1、變數提升

在JS程式碼執行之前,會先把程式碼從上到下瀏覽器一遍,然後把帶有var 和function的提前宣告

  • var的只宣告,不定義(就像只知道有個人,但是不知道是誰)
  • function的不僅宣告,還定義(即會把函式體當作字串放在堆記憶體中)

2、作用域(棧記憶體)

全域性作用域不能拿到私有作用域的變數,但是私有作用域可以拿全域性作用域的變數;

  • 全域性作用域
  • 私有作用域
    • 函式執行形成的作用域
    • ES6中新增的塊級作用域(如果把let和const放在if、while、for的{}內,那麼他們定義的變數就是這個{}內的私有變數,在{}外不可以訪問)

3、JS的執行

1、程式碼怎麼執行
第一步:首先進行語法檢測,(如果有問題就不再向下進行,因為JS是單執行緒,從上向下執行,只有程式碼報錯,就不向下執行了)如果沒有問題,就進行下一步
第二步:進行變數提升(聲),將帶有var 和function 的宣告出來放在棧記憶體的變數儲存區,並且把帶有function的定義一下(即把函式體放在自己重新開闢的堆記憶體中);
第三步:程式碼執行,此時執行的時候遇到var a = 12,就是直接去給在變數提升階段出來的a賦值;遇到function fn(){}時不要再操作;當遇到fn()執行這個函式的時候,再去開闢一個私有的棧記憶體進行函式的執行;

4、var 和 let的區別

1、在全域性作用域下,var 和function宣告的變數會給Window增加鍵值對,屬性名是變數名,屬性值是變數的值;
2、var 和function可以建立重複的變數,但是let 和const不可以,並且const定義的時候需要賦值,不賦值會報錯,而let不賦值是undefined;
3、不管之前通過什麼辦法宣告瞭一個變數,只要當前棧記憶體中存在了這個變數,使用let/const等再宣告都是語法報錯
4、var 和function 有變數提升,但是let 和 const 沒有

let a = 12;
let a = 12;
//報錯,因為let不允許重複宣告一個變數
複製程式碼
var a = 12;
let a = 12;
//會報錯,因為第一步對var變數提升,此時已經宣告a,瀏覽器中已經知道有a這個變數了,因此再使用let這個變數名就不可以了(依舊滿足let不允許重複宣告的機制)。
複製程式碼
let a = 12;
var a = 12;
//報錯;這種情況和第二種一樣
複製程式碼
b = 12;  //給Window增加鍵值對
var b = 12; //不僅給window增加鍵值對,還會建立全域性變數b
let b = 12; //
複製程式碼

前端 -- JS變數提升
前端 -- JS變數提升

5、作用域鏈

  • 變數的查詢機制:在某個作用域中要使用一個變數,先看這個變數是不是自己私有的,不是私有變數則去上級作用域查詢(指的是該函式是在哪個作用域形成的,那麼上級作用域就是那個作用域);
  • 只有在自己的作用域裡面定義的(變數提升出來),就是私有的,不能再去上級查詢;

6、函式在變數提升階段幹了什麼?

定義函式名,並且把函式體的內容以字串的方式儲存在新開闢的堆記憶體中,函式名關聯的是堆記憶體的地址。等後期呼叫函式的時候,函式體內的內容才去執行;

7、函式在執行的時候經歷那幾步

  • 開闢一個新的私有棧記憶體;
  • 形參賦值
  • 變數提升
  • 程式碼執行
  • 作用域是否被銷燬

8、例題

前端 -- JS變數提升

相關文章