ES6 介紹 及 變量基礎知識
一、ES6 簡介
ECMAScript 6.0(以下簡稱 ES6)是 JavaScript 語言的下一代標準,已經在 2015 年 6 月正式發布了。它的目標,是使得 JavaScript 語言可以用來編寫復雜的大型應用程序,成為企業級開發語言
ES6 是 5.1 版以後的 JavaScript 的下一代標準,涵蓋了 ES2015、ES2016、ES2017 等等;而 ES2015 則是正式名稱,特指該年發布的正式版本的語言標準
二、ES6 轉碼
Node 是 JavaScript 的服務器運行環境(runtime),它對 ES6 的支持度更高,但有些執行環境不能完全支持 ES6 語法
ES6 轉碼器 可以將 ES6 代碼轉為 ES5 代碼,從而在現有環境執行。
三、ES6 新特性匯總(待更新)
- 增加塊級作用域
四、變量的 聲明
1. 塊級作用域
ES6的塊級作用域,是通過
let
、const
聲明變量,來體現的只要一個代碼塊
{ }
中存在let
、const
,就形成了一個封閉的作用域(塊級作用域);每一個{ }
都是一層塊級作用域塊級作用域的出現,實際上使得獲得廣泛應用的立即執行函數表達式(IIFE)不再必要了
// IIFE 寫法
(function () {
var tmp = ...;
...
}());
// 塊級作用域寫法
{
let tmp = ...;
...
}
2. let 、const 聲明變量,詳解
(1)通過 let
、 const
聲明的變量,不是全局變量, 不能通過 window 訪問
- 只能在當前塊級作用域 及 子作用域內能夠被訪問到
(2)let
聲明變量,允許被修改
(3)const
聲明一個只讀的常量,不允許被修改
- 意味著:
const
一旦聲明變量,就必須立即初始化,不能留到以後賦值
const foo; // SyntaxError: Missing initializer in const declaration
- 本質:並不是變量的值不得改動,而是變量指向的那個內存地址不得改動;
簡單數據類型:值就保存在變量指向的那個內存地址,所以不能有任何改變
復雜數據類型:
const
const
只能約束 指針指向的內存地址不變;不能約束 內存地址中 的數據結構
// 所以:const 聲明復雜數據類型,其數據結構是可變的
const foo = {};
// 為 foo 添加一個屬性,可以成功
foo.prop = 123;
ondole.log(foo.prop); // 123
3. let 、const 聲明變量,不存在變量提升
let
、const
聲明變量,不存在變量提升
// var 的情況
console.log(foo); // 輸出undefined
var foo = 2;
// let 的情況
console.log(bar); // 報錯ReferenceError
let bar = 2;
4. let 、const 聲明變量,造成暫時性死區(TDZ)
let
、const
聲明變量,不允許 在變量聲明之前 使用,造成暫時性死區let
、const
聲明變量,形成塊級作用域,在聲明變量之前的區域,都是 變量的死區(不允許 使用變量,使用會報錯)
var tmp = 123;
if (true) {
// TDZ開始
tmp = ‘abc‘; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ結束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
// 上面代碼中,在let命令聲明變量tmp之前,都屬於變量tmp的“死區”
- 比較隱蔽的死區
function bar(x = y, y = 2) {
return [x, y];
}
console.log(bar()); // 報錯
5. let 、const 聲明變量,不允許重復聲明
- 對比:var 聲明的變量,重復聲明 無效,不會報錯
if (true) {
const a = 10;
const a = 1;
}
- 函數直接作用域內 使用
let
重新聲明形參,會報錯
function func(arg) {
let arg; // 報錯
}
- 內層作用域可以定義外層作用域的同名變量
function func(arg) {
{
let arg; // 不報錯
}
}
6. let 、 const 聲明的全局變量,不屬於頂層對象的屬性
ES5 敗筆之一:頂層對象的屬性與全局變量是等價的;很容易不知不覺的創建多個全局變量,讀寫困難,維護困難
- ES6 規定:
var命令和function命令聲明的全局變量,依舊是頂層對象的屬性
let命令、const命令、class命令聲明的全局變量,不屬於頂層對象的屬性
var a = 1;
console.log(window.a); // 1
let b = 1;
console.log(window.b); // undefined
五、變量的 解構賦值
1. 概念
- ES6 允許按照一定模式,從數組 和 對象中提取值,對變量進行賦值,這被稱為解構賦值(Destructuring)
2. 解構賦值 --- 數組
模式匹配 內部機制:數組的元素是按次序排列的,相同位置 數據結構相同,才能成功的解構賦值
分為:存在完全結構賦值,和不完全結構賦值
// 完全結構賦值
let [foo, [[bar], baz]] = [1, [[2], 3]];
console.log(foo); // 1
console.log(bar); // 2
console.log(baz); // 3
// 不完全結構賦值
let [x, y] = [1, 2, 3];
console.log(x); // 1
console.log(y); // 2
// `...a` 代表定義數組
let arr = [1, 2, 3, 4];
let [a, b, ...c] = arr;
console.log(c); // [3, 4]
- 結構賦值 數組的長度(因為數組 有
length
屬性)
let arr = [1, 2, 3];
let {length: leg} = arr;
console.log(leg); // 3
2. 解構賦值 --- 對象
- 模式匹配 內部機制:先在已有對象中找到同名屬性,然後再將已有對象中同名屬性的值 賦給 定義變量的屬性值
// 定義的變量名 與 屬性名一致
let { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
let { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined
// 定義的變量名 與 屬性名不一致
let { foo: baz } = { foo: ‘aaa‘, bar: ‘bbb‘ };
console.log(baz); // "aaa"
3. 解構賦值 --- 指定默認值
- 默認值生效的條件是,數組 / 對象 的屬性值 嚴格等於
undefined
let [x = 1] = [undefined];
console.log(x); // 1
let [y = 1] = [null];
console.log(y); // null
- 如果默認值是一個表達式,那麽這個表達式是惰性求值的(只有在用到的時候,才會求值)
function f() {
console.log(‘aaa‘);
}
let [x = f()] = [1]; // 無輸出
let [x = f()] = []; // aaa
- 默認值可以引用解構賦值的其他變量,但該變量必須已經聲
let [x = 1, y = x] = []; // x=1; y=1
let [x = 1, y = x] = [2]; // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = []; // ReferenceError
4. 解構賦值 --- 函數 參數
function move({x = 0, y = 0} = {}) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]
5. 解構賦值 的用途
交換變量
let x = 1;
let y = 2;
[x, y] = [y, x];
函數 設置默認參數
function(n = 1) {
return n;
}
函數 參數為對象 設置默認值
function foo({
x = 10,
y = 5
}) {
console.log(x, y);
}
foo({}) // undefined 5
foo({x: 1}) // 1 5
foo() // TypeError: Cannot read property ‘x‘ of undefined
function foo({
x = 10,
y = 5
} = {}) {
console.log(x, y);
}
foo({}) // undefined 5
foo({x: 1}) // 1 5
foo() // 1 5
提取 對象 / json 中的數據
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number);
// 42, "OK", [867, 5309]
ES6 介紹 及 變量基礎知識