1. 程式人生 > >ES6 介紹 及 變量基礎知識

ES6 介紹 及 變量基礎知識

函數表達式 status 執行函數 java 5.1 ber 聲明 設置 模式匹配

一、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的塊級作用域,是通過 letconst 聲明變量,來體現的

  • 只要一個代碼塊 { } 中存在 letconst ,就形成了一個封閉的作用域(塊級作用域);每一個 { } 都是一層塊級作用域

  • 塊級作用域的出現,實際上使得獲得廣泛應用的立即執行函數表達式(IIFE)不再必要了

// IIFE 寫法
(function () {
    var tmp = ...;
    ...
}());

// 塊級作用域寫法
{
    let tmp = ...;
    ...
}

2. let 、const 聲明變量,詳解

(1)通過 letconst 聲明的變量,不是全局變量, 不能通過 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 聲明變量,不存在變量提升

  • letconst 聲明變量,不存在變量提升
// var 的情況
console.log(foo); // 輸出undefined
var foo = 2;

// let 的情況
console.log(bar); // 報錯ReferenceError
let bar = 2;

4. let 、const 聲明變量,造成暫時性死區(TDZ)

  • letconst 聲明變量,不允許 在變量聲明之前 使用,造成暫時性死區

  • letconst 聲明變量,形成塊級作用域,在聲明變量之前的區域,都是 變量的死區(不允許 使用變量,使用會報錯)

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 介紹 及 變量基礎知識