1. 程式人生 > >過一遍ES6(二)--- 陣列的解構賦值

過一遍ES6(二)--- 陣列的解構賦值

解構:ES6按照一定的模式,從陣列和物件中提取值,對變數進行賦值

陣列的結構賦值

形式: 從陣列中提取值,按照對應的位置,對變數賦值

let [a, b, c] = [1, 2, 3]

巢狀資料進行結構
本質上,這種寫法屬於“模式匹配”,只要等號兩邊的模式相同,左邊的變數就會被賦予對應的值。

let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3

let [ , , third] = ["foo", "bar", "baz"];
third // "baz"

let [x, , y] = [1, 2, 3];
x // 1
y // 3 let [head, ...tail] = [1, 2, 3, 4]; head // 1 tail // [2, 3, 4] let [x, y, ...z] = ['a']; x // "a" y // undefined z // []

如果解構不成功,則變數值為undefined
(變數數量大於值的數量)

let [foo] = [];       // foo值為undefined
let [bar, foo] = [1]; // foo值為undefined

不完全解構(值的數量大於變數的數量)

let [x, y] = [1, 2, 3];
x // 1
y // 2

let [a, [b], d] = [1
, [2, 3], 4]; a // 1 b // 2 d // 4

解構報錯
左邊為陣列形式,當右邊為不可遍歷的結構,則將會報錯

let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};

set結構使用陣列的解構賦值

let [x, y, z] = new Set(['a', 'b', 'c']);
x // "a"

只要某種資料結構具有Iterator介面,都可以採用陣列形式的解構賦值
下面程式碼中的fibs函式是一個Generator函式。
簡單介紹Generator函式(後續會進一步介紹):

  • 執行Generator函式將返回一個遍歷器物件
  • 返回的遍歷器物件,可以依次遍歷Generator函式內部的每一個狀態
  • Generator函式體內部的yield表示式定義不同的內部狀態,遍歷時遇到yield將會暫停,繼續遍歷時繼續執行yield後面的程式碼。每一次遍歷返回的value值為yield後的狀態值或者return的值。
function* fibs() {
  let a = 0;
  let b = 1;
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

let [first, second, third, fourth, fifth, sixth] = fibs();
sixth // 5
// 該函式執行的結果:
// 根據while迴圈中的語句:
//  yield a;
//  [a, b] = [b, a + b];
// 每次獲取到a的值,之後重新給a和b賦值
// first = 0 ⇒ [a,b] = [1, 1]
// second= 1 ⇒ [a,b] = [1, 2]
// third = 1 ⇒ [a,b] = [2, 3]
// fourth= 2 ⇒ [a,b] = [3, 5]
// fifth = 3 ⇒ [a,b] = [5, 8]
// sixth = 5 ⇒ [a,b] = [8, 13]

指定預設值
在解構賦值中允許指定預設值
*注意:ES6內部使用嚴格相等運算子(===),判斷一個位置是否有值。所以,只有當一個數組成員嚴格等於undefined,預設值才生效
例如:

let [x = 1] = [undefined];
x // 1

// 由於null不嚴格等於undefined,所以預設值不會生效
let [x = 1] = [null];
x // null

如果預設值為是表示式:表示式是惰性求職的,即只有在用到的時候,才會求值

function f() {
  console.log('aaa');
}

let [x = f()] = [1];

由於x能夠取到值,所以函式f不會執行。上述程式碼等價於下面的程式碼:

let x;
if ([1][0] === undefined) {
  x = f();
} else {
  x = [1][0];
}

預設值可以引用解構賦值的其他變數,但該變數必須已經宣告

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: y is not defined

在最後一個表示式中,由於x用y做為預設值,但是此時y還沒有宣告,所以將會報錯