【ES6】let 與 const 用法這些就夠了
ECMAScript與JavaScript的關係
ECMAScript
是JavaScript
語言的國際標準,JavaScript
是ECMAScript
的實現。
let 與 const 的用法
let
用來宣告變數
,所宣告的變數只在let
命令所在的程式碼塊
內有效。
const
用來宣告常量
,所謂常量就是物理指標不可以更改
的變數。
1、程式碼塊與塊級作用域
{ let a = 1; } console.log(a)// 報錯 a is not defined
-
只需要用
{}
包起來,這個{}
和其中程式碼生成一個程式碼塊 ; -
在塊中,
let
和const
宣告的變數和常量對外都是不可見的,稱之為塊級作用域 ; -
只有使用
let
和const
宣告的變數或者常量在塊中對外不可見,var宣告的變數對外依然可見; - 可以認為是let和const建立了塊級作用域 。
塊級作用域特性
(1)ES6 允許塊級作用域的任意巢狀
{{{{{let insane = 'Hello World'}}}}};
(2)外層作用域無法讀取內層作用域的變數
{{{{ {let insane = 'Hello World'} console.log(insane); // 報錯 }}}};
(3)內層作用域可以定義外層作用域的同名變數
{{{{ let insane = 'Hello World'; {let insane = 'Hello World'} }}}};
2、let指令
- (1)let宣告的變數只在變數宣告時所在的程式碼塊內有效。
{ let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1
- (2)不存在變數提升現象
var
命令會發生”變數提升
“現象,即變數可以在宣告之前使用,值為undefined
;但let
所宣告的變數一定要在聲明後使用,否則報錯。
// var 的情況 console.log(foo); // 輸出undefined var foo = 2; // let 的情況 console.log(bar); // 報錯ReferenceError let bar = 2;
- (3)暫時性死區
在程式碼塊內,使用let
命令宣告變數之前,該變數都是不可用的。這在語法上,稱為“暫時性死區
”(TDZ)。
if (true) { // TDZ開始 tmp = 'abc'; // ReferenceError console.log(tmp); // ReferenceError let tmp; // TDZ結束 console.log(tmp); // undefined tmp = 123; console.log(tmp); // 123 }
暫時性死區的本質就是,只要一進入當前作用域,所要使用的變數就已經存在了,但是不可獲取,只有等到宣告變數的那一行程式碼出現,才可以獲取和使用該變數。
-
(4)
let
不允許在同一作用域重複宣告變數
// 報錯 function func() { let a = 10; var a = 1; } // 報錯 function func() { let a = 10; let a = 1; }
同時,也不能在函式內部重新宣告引數
function func(arg) { let arg; // 報錯 } function func(arg) { { let arg; // 不報錯 } }
-
(5)關於
for
迴圈
for
迴圈的計數器,很合適使用let
命令,在for
迴圈中使用let
定義變數,只在for
的迴圈週期內可以使用,在迴圈體外引用就會報錯
for (let i = 0; i < 10; i++) { // ... } console.log(i); // ReferenceError: i is not defined
for
迴圈設定迴圈變數的那部分是一個父作用域,而迴圈體內部是一個單獨的子作用域
for (let i = 0; i < 3; i++) { let i = 'abc'; console.log(i); } // abc // abc // abc
3、const指令
-
(1)
const
宣告一個只讀的常量。一旦宣告,常量的值就不能改變。
const PI = 3.1415; PI // 3.1415 PI = 3; // TypeError: Assignment to constant variable.
-
(2)
const
一旦宣告變數,就必須立即初始化,只宣告不賦值,就會報錯。
const foo; // SyntaxError: Missing initializer in const declaration
-
(3)
const
的作用域與let
命令相同:只在宣告所在的塊級作用域內有效。
if (true) { const MAX = 5; } MAX // Uncaught ReferenceError: MAX is not defined
-
(4)
const
命令宣告的常量也是不提升,同樣存在暫時性死區,只能在宣告的位置後面使用。
if (true) { console.log(MAX); // ReferenceError const MAX = 5; }
-
(5)
const
宣告的常量,也與let
一樣在同一作用域中不可重複宣告。
var message = "Hello!"; let age = 25; // 以下兩行都會報錯 const message = "Goodbye!"; const age = 30;
-
(6)
const
實際上保證的,並不是變數的值不得改動,而是變數指向的那個記憶體地址 不得改動。- 對於簡單型別的資料(數值、字串、布林值) ,值就儲存在變數指向的那個記憶體地址,因此等同於常量。
-
對於複合型別的資料(主要是物件和陣列)
,變數指向的記憶體地址,儲存的只是一個指向實際資料的指標,
const
只能保證這個指標是固定的(即總是指向另一個固定的地址),至於它指向的資料結構是不是可變的,就完全不能控制了。
const foo = {}; // 為 foo 新增一個屬性,可以成功 foo.prop = 123; foo.prop // 123 // 將 foo 指向另一個物件,就會報錯 foo = {}; // TypeError: "foo" is read-only
上面程式碼中,
常量foo
儲存的是一個地址,這個地址指向一個物件。不可變的只是這個地址,即不能把foo
指向另一個地址,但物件本身是可變的,所以依然可以為其新增新屬性
。
4、ES6 宣告變數的六種方法
var function let const import class