[JS] Destructuring 的用法

在弄清楚它是什麼之前,不知道它到底可以幹嘛用。
弄清楚之後才恍然大悟,原來它真的蠻好用!

基礎用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var a, b, rest;
[a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20

[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]

({ a, b } = { a: 10, b: 20 });
console.log(a); // 10
console.log(b); // 20

({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(a); // 10
console.log(b); // 20
console.log(rest); //{c: 30, d: 40}

解構賦值可以用在 array 和 object 上。也可以混著使用,後面會說到。
透過解構賦值可以簡單的宣告變數,不用再一個一個的去宣告。

陣列的解構賦值

  • 可以賦予預設值。
  • 可以對調變數值。

忽略部分的值

  • 使用 , 和空白做分隔,就可以忽略不需要的值。
1
2
3
4
5
6
7
function f() {
return [1, 2, 3];
}

var [a, , b] = f();
console.log(a); // 1
console.log(b); // 3

Rest 的使用

  • 使用 ... 可以擷取剩下的值。
  • 要特別注意,它只能使用在最後一個變數。
1
2
3
var [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]

如果 rest 不是最後一個變數,會跳錯誤。

1
2
var [a, ...b,] = [1, 2, 3];
// SyntaxError: rest element may not have a trailing comma

物件的解購賦值

  • 基本上和陣列的解構賦值是相同的。
  • 可以重新命名變數名稱,也可以給予變數預設值。
  • 需要注意,object destructuring 若是在事先宣告的情況下,需要有 ( ) 將它包覆起來。

    1
    2
    var a, b;
    ({a, b} = {a: 1, b: 2});
  • 物件的 rest 用法

    1
    2
    3
    4
    let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
    a; // 10
    b; // 20
    rest; // { c: 30, d: 40 }

巢狀的物件和陣列解構 (Nested object and array destructuring)

With Object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function makeItem(){
return {
data: {
item: {
name: 'Shoes',
size: {
US: 10,
EU: 44
}
}
},
status: 'live';
}
}
1
2
3
4
5
6
7
8
9
const res = makeItem()
const {data, status} = res;
console.log(data, status); // data 會是 item 物件; status: 'live'

// data 這個變數是不存在的,它只是用來取得 item 的路徑
const {data: {item}} = res;

// 可以繼續解構下去。同時也可以更改變數名稱
const {data: {item: {name, size:{ US: weird, EU: normal}}}} = res;

With Array & Object

  • 陣列和物件的解構賦值可以混合使用。
1
2
3
4
5
6
7
8
9
10
11
function makeArryItems(){
return {
data: {
items: [
{name: 'Shoes', price: 100},
{name: 'Size', price: 250}
]
},
status: 'live'
}
}
1
2
3
4
const  res = makeArryItems();
const {data:{items: [item1, item2]}} = res;

const {data:{items: [{name:name1, price:price1},{name:name2, price:price2}]}} = res;

在迭代使用解構賦值 (For of iteration and destructuring)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var people = [
{
name: 'Mike Smith',
family: {
mother: 'Jane Smith',
father: 'Harry Smith',
sister: 'Samantha Smith'
},
age: 35
},
{
name: 'Tom Jones',
family: {
mother: 'Norah Jones',
father: 'Richard Jones',
brother: 'Howard Jones'
},
age: 25
}
];

for (var {name: n, family: {father: f}} of people) {
console.log('Name: ' + n + ', Father: ' + f);
}

// "Name: Mike Smith, Father: Harry Smith"
// "Name: Tom Jones, Father: Richard Jones"

在 function parameter 中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function userId({id}) {
return id;
}

function whois({displayName, fullName: {firstName: name}}) {
console.log(displayName + ' is ' + name);
}

var user = {
id: 42,
displayName: 'jdoe',
fullName: {
firstName: 'John',
lastName: 'Doe'
}
};

console.log('userId: ' + userId(user)); // "userId: 42"
whois(user); // "jdoe is John"

參考資料

destructuring MDN
Nested Object Destructuring works