在JavaScript中可以使用var、let和const三種修飾符來聲明變量,使用的場景有所不同。
1.使用var聲明的變量會掛載到window上,而使用let和const聲明的變量則不會。
var yanggb = 100; console.log(yanggb, window.yanggb); // 100 100 let yanggb1 = 10; console.log(yanggb1, window.yanggb1); // 10 undefined const yanggb2 = 1; console.log(yanggb2, window.yanggb2); // 1 undefined
2.使用var聲明的變量存在聲明提升的特性,而使用let和const聲明的變量則不會。
console.log(yanggb); // undefined,相當於var yanggb; console.log(yanggb); yanggb = 100; var yanggb = 100;
console.log(yanggb1); // 報錯:yanggb1 is not defined let yanggb1 = 10;
console.log(yanggb2); // 報錯:yanggb2 is not defined const yanggb2 = 10;
這一特性同時也使得可以使用var在統一作用域下聲明同名變量,而使用let和const則不行。
var yanggb = 100; console.log(yanggb); // 100 var yanggb = 10; console.log(yanggb); // 10
上面這段代碼實際上相當於:
var yanggb; yanggb = 100; console.log(yanggb); // 100 yanggb = 10; console.log(yanggb); // 10
而同樣的邏輯使用let或const則會報錯:
let yanggb = 100; console.log(yanggb); // 100 let yanggb = 10; // 報錯:Identifier 'yanggb' has already been declared
3.使用var聲明的變量會超脫出塊級作用域(for循環中的花括號或if中的花括號),而使用let和const聲明的變量則不會。
if (true) { var a = 100; let b = 100; const c = 100; } console.log(a); // 100 console.log(b); // 報錯:b is not defined console.log(c); // 報錯:c is not defined
for (var yanggb = 0; yanggb < 100; yanggb++) { // .. } console.log(yanggb); // 100 for (let yanggb1 = 0; yanggb1 < 100; yanggb1++) { // .. } console.log(yanggb1); // 報錯:yanggb1 is not defined
4.使用let命令會帶來暫時性死區(temporal dead zone,簡稱TDZ)。
var yanggb = 100; if (true) { // TDZ開始 yanggb = 10; console.log(yanggb); // 在當前塊作用域中存在使用let/const聲明的情況下, // 給yanggb賦值10時,只會在當前作用域找變量a, // 而這時,還未到聲明時候,所以控制台Error:yanggb is not defined let yanggb = 1; // TDZ結束 console.log(yanggb); } console.log(yanggb); // 100,不受塊級作用域中聲明的變量的影響
只要塊級作用域內存在let命令,它所聲明的變量就被綁定在這個區域內,不再受外部的影響重點內容。簡單理解就是,就是只要某個代碼塊有let指令,即使外部有名稱相同的變量,該代碼塊的同名變量與外部的變量也互不干擾。
5.const聲明的變量必須具備初始值且聲明后不可修改,是最嚴格的語法,通常用於聲明常量。
const yanggb = 100; yanggb = 666; console.log(yanggb); // 100
但是如果聲明的變量是復合類型的,則是可以修改其內部屬性的,這時可以看作只是類型不可改變。
const yanggb = []; yanggb[0] = 10; console.log(yanggb); // [10] const yanggb1 = {}; yanggb1.name = 'yanggb1'; console.log(yanggb1); // {name: 'yangb1'}
總結
var是歷史存留的語法,在新的規范中基本上都不建議使用了(過於靈活,容易失去控制);而let和const的選用則是要根據場景而定,如果聲明的是常量(聲明后不再改變其值),則使用const;如果聲明之后會改變值,則可以使用let(理論上用得最多)。
"人生就像一場煙花,你盛裝而來,卻只是爭得片刻的輝煌和美麗。"