解構賦值
解構賦值可以將數組中的元素或對象中的屬性賦值給指定的變量。
1. 數組解構
1.1 基本用法
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]
// 變參後不能加逗號
var [a, ...b,] = [1, 2, 3];
// SyntaxError: rest element may not have a trailing comma
// 對象解構
({ 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}
上面的例子都是數組字面量或對象字面量的解構,但實際上大部分情況時對變量的解構。
var foo = ['one', 'two', 'three'];
// 變量解構
var [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"
// 數組長度更長
var arr = [1, 2, 3, 4, 5];
var [x,y] = arr;
console.log(x); // 1
console.log(y); // 2
// 數組長度過端
var arr = [];
var [x,y] = arr;
console.log(x); // undefined
console.log(y); // undefined
// 數組過短,提供默認值
var arr = [];
var [x=5,y=7] = arr;
console.log(x);
console.log(y);
1.2 使用解構賦值實現變量交換
var a = 1;
var b = 3;
[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1
1.3 解構函數返回值
function f() {
return [1, 2];
}
var a, b;
[a, b] = f();
console.log(a); // 1
console.log(b); // 2
1.4 忽略某些返回值
function f() {
return [1, 2, 3];
}
var [a, , b] = f();
console.log(a); // 1
console.log(b); // 3
// 忽略所有返回值
[,,] = f();
1.5 數組解構與正則結合使用的實例
// 使用正則和賦值解構獲取url中的協議、主機、路徑等信息
function parseProtocol(url) {
var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
if (!parsedURL) {
return false;
}
console.log(parsedURL);
// ["https://developer.mozilla.org/en-US/Web/JavaScript", "https", "developer.mozilla.org", "en-US/Web/JavaScript"]
var [, protocol, fullhost, fullpath] = parsedURL;
return protocol;
}
console.log(parseProtocol('https://developer.mozilla.org/en-US/Web/JavaScript')); // "https"
2. 對象解構
2.1 基本用法
var o = {p: 42, q: true};
var {p, q} = o;
console.log(p); // 42
console.log(q); // true
2.2 對象字面量的解構
var a, b;
({a, b} = {a: 1, b: 2});
爲了避免對象字面量的大括號
{ }
與代碼塊的大括號混淆,字面量解構的時候需要在外層包裹一個小括號( )
。
2.3 爲解構的對象屬性值定義新的變量名
var o = {p: 42, q: true};
var {p: foo, q: bar} = o;
console.log(foo); // 42
console.log(bar); // true
2.4 屬性默認值
對於不存在的屬性,默認解構得到的屬性爲undefined
,但是可以設置默認值
var {a, b} = {a: 3};
console.log(a); // 3
console.log(b); // undefined
// 提供默認值
var {a = 10, b = 5} = {a: 3};
console.log(a); // 3
console.log(b); // 5
2.5 同時提供默認值並取新變量名
var {a:aa = 10, b:bb = 5} = {a: 3};
console.log(aa); // 3
console.log(bb); // 5
2.6 對象解構與函數默認參數結合使用的實例
// ES5版本:函數參數默認值的設置
function drawES5Chart(options) {
options = options === undefined ? {} : options;
var size = options.size === undefined ? 'big' : options.size;
var cords = options.cords === undefined ? {x: 0, y: 0} : options.cords;
var radius = options.radius === undefined ? 25 : options.radius;
console.log(size, cords, radius);
// now finally do some chart drawing
}
// 調用ES5函數
drawES5Chart({
cords: {x: 18, y: 30},
radius: 30
});
// ES6版本:函數參數默認值的設置
function drawES2015Chart({size = 'big', cords = {x: 0, y: 0}, radius = 25} = {}) {
console.log(size, cords, radius);
// do some chart drawing
}
drawES2015Chart({
cords: {x: 18, y: 30},
radius: 30
});
2.7 對象解構和數組解構嵌套使用
var metadata = {
title: 'Scratchpad',
translations: [
{
locale: 'de',
localization_tags: [],
last_edit: '2014-04-14T08:43:37',
url: '/de/docs/Tools/Scratchpad',
title: 'JavaScript-Umgebung'
}
],
url: '/en-US/docs/Tools/Scratchpad'
};
var {title: englishTitle, translations: [{title: localeTitle}]} = metadata;
console.log(englishTitle); // "Scratchpad"
console.log(localeTitle); // "JavaScript-Umgebung"
2.8 循環迭代中使用解構賦值
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"
2.9 通過對象解構直接從函數參數中獲取對象字段
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"
2.10 動態解構對象字段
let key = 'z';
// key是變量
let {[key]: value} = {x: 'X', y: 'Y', z: 'Z'};
console.log(value); // "Z"
2.11 變參解構切割對象
let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
a; // 10
b; // 20
rest; // { c: 30, d: 40 }
2.12 解構特殊屬性
// fizz-buzz屬性不能作爲變量名
const foo = { 'fizz-buzz': true };
// 這裏就必須取別名
const { 'fizz-buzz': fizzBuzz } = foo;
console.log(fizzBuzz); // "true"
參考:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment