首頁 > 軟體

JavaScript變數中var,let和const的區別

2022-09-12 18:00:24

前言

JavaScript中一共有3種用來宣告變數的關鍵字,分別是var、let和const。

其中var關鍵字是ES5時代的產物,由於ES5對變數的約束很寬鬆,使用var來宣告變數時經常會出現一些預料之外的問題。 ES6為了使變數的定義更加規範,提出了let和const這兩個關鍵字。

因此要解釋清楚這三個的區別,首先要從ES5時代和ES6時代的差別說起,主要是var和let的區別。

ES5與ES6的區別

1. 作用域

使用不同的關鍵字來宣告變數,主要就是對變數的作用域有不同的限制,因此var和let最主要的區別就是變數作用域的區別。

  • var宣告的範圍是函數作用域,函數體之外無法存取到函數體內宣告的var變數。

做題的時候經常會有在全域性和函數體內宣告同名變數的場景,要知道不同作用域的變數是不會互相干擾的。

var a = 10;
function logA() {
    var a = 20;
    console.log(a); // 20
}
console.log(a); // 10
  • let宣告的範圍是塊作用域,塊作用域是函數作用域的子集,可以使用花括號{...}來限定塊級作用域。

2. 全域性屬性

在全域性作用域下使用var和let宣告變數,變數都是會在頁面的宣告週期記憶體續。

但是使用var宣告的變數會成為window物件的屬性,使用let宣告則不會

3. 變數提升與暫時性死區

  • var宣告存在變數提升的行為

變數的宣告、初始化和賦值被分為三步進行,對於var變數,宣告和初始化會被提升到作用域的頂部。

也就是說,編譯器在遇到var宣告時,會先在作用域頂部宣告一個var變數並將其初始化為undefined值。

因此在程式碼執行流遇到var宣告語句之前存取var變數並不會報錯,而是會存取到undefined值。

(function example() {
  console.log(age); // undefined
  var age = 20;
})();

// 相當於
(function example() {
  var age;
  console.log(age); // undefined
  age = 20;
})();
  • ES6對先存取後宣告變數的行為做了約束,因此let和const宣告會存在TDZ暫時性死區

即JavaScript引擎在編譯時如果遇到let和const宣告,會將它們放入暫時性死區以阻止存取,只有在執行到變數宣告的語句後,才會將變數從TDZ中移出。

因此如果在變數宣告語句之前存取變數,相當於企圖存取TDZ中的變數,JavaScript會丟擲執行時錯誤ReferenceError

ES5的變數提升和ES6的暫時性死區的區別還有一個“副作用”就是改變了typeof操作對於變數的存取性。

已知在ES5時對於未宣告變數唯一的安全操作是typeof,會返回undefined值。

TDZ的出現導致即使使用typeof,也不能在let和const宣告語句執行之前存取let和const變數,依然會報ReferenceError

4. 重複宣告

  • var宣告是允許重複的,可以重複使用var關鍵字來宣告同名變數,後來宣告的變數值會覆蓋之前的值。
  • 為了阻止重複宣告變數這個容易讓人迷惑的行為,ES6限制了let和const宣告的變數都是不可重複的,如果重複宣告會報SyntaxError錯誤。

這個限制不僅體現在let宣告對let宣告,如果想用let去重複宣告var變數也是不被允許的。

let與const的區別

1. 常數

同樣都是ES6的變數宣告關鍵字,let和const的區別就在於使用const宣告建立的是一個值的唯讀參照

唯讀參照意味著對於原始值來說,const宣告不可以再重新賦值;

對於參照值來說,const宣告不可以再修改參照,但是可以修改物件的屬性值或者陣列內部的值。

最佳實踐

  • 儘量不使用var。因為let和const已經可以替代var的位置,滿足開發需求,順便還規避了很多不必要的問題。
  • 優先使用const宣告,let宣告次之。const宣告有點像保護變數的機制,它能預防和阻止預期之外的變數修改。 對於有修改需求的變數,就使用let宣告。

到此這篇關於JavaScript變數中var,let和const的區別的文章就介紹到這了,更多相關JS var,let,const內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


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