本篇文章主要是向大家分享了關於ES6系列的聲明變數let與const,有興趣的朋友們可以參考一下本文中的內容
簡介
概念
ES6 的第一個版本,在 2015 年 6 月發布了,正式名稱就是《ECMAScript 2015 標準》(簡稱 ES2015)。ES6 既是一個曆史名詞,也是一個泛指,含義是 5.1 版以後的 JavaScript 的下一代標準,涵蓋了 ES2015、ES2016、ES2017 等等,而 ES2015 則是正式名稱,特指該年發布的正式版本的語言標準。
各大瀏覽器對ES6的支援:kangax
Babel
Babel 是一個廣泛使用的 ES6 轉碼器,可以將 ES6 代碼轉為 ES5 代碼,從而在現有環境執行。
Babel 的設定檔是.babelrc,存放在項目的根目錄下。使用 Babel 的第一步,就是配置這個檔案。
聲明變數
ES5 只有兩種聲明變數的方法:var命令和function命令,ES6 除了添加let、const、import和class命令。所以,ES6 一共有 6 種聲明變數的方法。
ES5 之中,頂層對象的屬性與全域變數是等價的。ES6 為了改變這一點,一方面規定,為了保持相容性,var命令和function命令聲明的全域變數,依舊是頂層對象的屬性;另一方面規定,let命令、const命令、class命令聲明的全域變數,不屬於頂層對象的屬性。也就是說,從 ES6 開始,全域變數將逐步與頂層對象的屬性脫鉤。
let
ES6 新增了let命令,用來聲明變數。它的用法類似於var,但是所聲明的變數,只在let命令所在的代碼塊內有效。
{ let a = 10; var b = 1;}a // ReferenceError: a is not defined.b // 1
不允許重複聲明
let不允許在相同範圍內,重複聲明同一個變數。
// 報錯function func() { let a = 10; var a = 1;}function func(arg) { let arg; // 報錯}function func(arg) { { let arg; // 不報錯 }}
塊級範圍
ES6 允許塊級範圍的任意嵌套。
內層範圍可以定義外層範圍的同名變數。
外層範圍無法讀取內層範圍的變數。
{{{{ {let insane = 'Hello World' {let insane = 'Hello World'} } console.log(insane); // 報錯}}}};
塊級範圍與函式宣告
考慮到環境導致的行為差異太大,應該避免在塊級範圍內聲明函數。如果確實需要,也應該寫成函數運算式,而不是函式宣告語句。
不存在變數提升
let命令所聲明的變數一定要在聲明後使用,否則報錯。
// var 的情況console.log(foo); // 輸出undefinedvar foo = 2;// let 的情況console.log(bar); // 報錯ReferenceErrorlet bar = 2;
暫時性死區
只要塊級範圍記憶體在let命令,它所聲明的變數就“綁定”(binding)這個地區,不再受外部的影響。
var tmp = 123;if (true) { tmp = 'abc'; // ReferenceError let tmp;}
在代碼塊內,使用let命令聲明變數之前,該變數都是停用。這在文法上,稱為“暫時性死區”(temporal dead zone,簡稱 TDZ)。
const
const聲明一個唯讀常量。一旦聲明,常量的值就不能改變。
const PI = 3.1415;PI // 3.1415PI = 3;// TypeError: Assignment to constant variable.
本質
const實際上保證的,並不是變數的值不得改動,而是變數指向的那個記憶體位址不得改動。對於簡單類型的資料(數值、字串、布爾值),值就儲存在變數指向的那個記憶體位址,因此等同於常量。但對於複合類型的資料(主要是對象和數組),變數指向的記憶體位址,儲存的只是一個指標,const只能保證這個指標是固定的,至於它指向的資料結構是不是可變的,就完全不能控制了。因此,將一個對象聲明為常量必須非常小心。
const foo = {};// 為 foo 添加一個屬性,可以成功foo.prop = 123;foo.prop // 123// 將 foo 指向另一個對象,就會報錯foo = {}; // TypeError: "foo" is read-only
如果真的想將對象凍結,應該使用Object.freeze方法。
const foo = Object.freeze({});// 常規模式時,下面一行不起作用;// strict 模式時,該行會報錯foo.prop = 123;