首頁 > 軟體

JavaScript塊級作用域繫結以及狀態提升詳解

2022-03-15 16:02:59

前言

在ES6之前,JavaScript只有經典的var宣告,這給開發者帶來了很多的困擾。在ES6出現後,又增加了let和const關鍵字的宣告方式。這裡會講有關變數宣告,作用域,狀態提升相關知識。

作用域/執行上下文

在JavaScript的世界裡,作用域可以分為三種,分別是全域性作用域,函數作用域,塊級作用域。

  • 全域性作用域/執行上下文:預設或者是最基礎的作用域。一個程式只有一個全域性作用域,在JavaScript指令碼存在的生命週期中都在執行堆疊的底部不會被彈出銷燬。全域性作用域中有一個全域性物件(以瀏覽器環境為例,這個全域性物件是window)。
  • 函數作用域:一個函數體內部是一個作用域。
  • 塊級作用域:存在於塊中——字元 { 和 } 之間的區域。(顯然函數體也是由大括號包裹的,所以函數作用域也是塊級作用域)

var 宣告

var宣告在全域性作用域中,會被新增到全域性物件上成為全域性物件的屬性。在函數作用域中則會被提升到函數頂部。而且不管實際是否會執行,都會在預編譯階段將函數宣告提升,初始化操作則留在本地。

  • var宣告的變數會被提升到當前作用域頂部(當前作用域只包括全域性作用域或函數作用域,沒有塊級作用域)。

塊級宣告

臨時死區(Temporal Dead Zone,TDZ):用來描述 let 和 const 的不提升效果的術語。JavaScript引擎在掃描程式碼發現變數宣告時,要麼將他們提升到作用域頂部(var宣告),要麼將宣告放到TDZ(let宣告和const宣告)。存取在TDZ中的變數會觸發執行時錯誤,只有執行過變數宣告語句後,變數才會從TDZ中移出,然後才可以正常存取。

const 和 let 是塊級識別符號,所以宣告的變數、常數也只在當前程式碼塊中有效,一旦執行到塊外就會立即被銷燬。

  • let宣告:可以將變數作用域限制在當前程式碼塊中。在宣告語句前會將變數放在臨時死區。
  • const宣告:用來宣告常數,並且每個被被const宣告的常數必須進行初始化。如果是物件,則物件中的值可以修改(cosnt宣告不允許修改繫結,但可以修改繫結的值)

不宣告的變數

在JavaScript中,定義一個變數不使用關鍵字宣告也不會報錯。但不建議這麼做。

不管在全域性,函數還是塊作用域裡,a = 0 這樣的語句都會在 window 物件上建立 a 屬性,實際上也就是執行了 window.a = 0 。而只有在全域性作用域中,var a = 0才會在 window 上建立屬性 a,即為 window.a = 0。

1. 不使用關鍵字宣告變數

function func() {
    b = 0
    console.log(b);
    console.log(b === window.b);
}
func()
console.log(b === window.b);

// 輸出結果
/*
0
true
true
*/


IT145.com E-mail:sddin#qq.com