@xiaoyixy
2018-11-08T17:06:07.000000Z
字数 4337
阅读 1171
Note
ES6
ECMAScript6
解构赋值语法是一个 Javascript 表达式,这使得可以将值从数组或属性从对象提取到不同的变量中。
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
// Stage 3 proposal
({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}
// Basic variable assignment
var foo = ['one', 'two', 'three'];
var [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"
// Assignment separate from declaration
var a, b;
[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2
// Default values
var a, b;
[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7
// Swapping variables
var a = 1;
var b = 3;
[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1
// Ignoring some returned values
function f() {
return [1, 2, 3];
}
var [a, , b] = f();
console.log(a); // 1
console.log(b); // 3
// ignore all returned values:
[,,] = f();
// Assigning the rest of an array to a variable\
var [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]
// 剩余元素必须是数组的最后一个元素
var [a, ...b,] = [1, 2, 3];
// SyntaxError: rest element may not have a trailing comma
// Basic assignmentSection
var o = {p: 42, q: true};
var {p, q} = o;
console.log(p); // 42
console.log(q); // true
// Assignment without declarationSection
var a, b;
/*
* 赋值语句周围的(...) 是使用对象字面解构赋值时不需要声明的语法。
* {a, b} = {a: 1, b: 2}不是有效的独立语法,因为左边的{a, b}被认为是一个块而不是对象字面量。
* ({a, b} = {a: 1, b: 2})是有效的语法,它等价于 var {a, b} = {a: 1, b: 2}
*/
({a, b} = {a: 1, b: 2});
// Assigning to new variable names
var o = {p: 42, q: true};
var {p: foo, q: bar} = o;
console.log(foo); // 42
console.log(bar); // true
// Default values
var {a = 10, b = 5} = {a: 3};
console.log(a); // 3
console.log(b); // 5
// Assigning to new variables names and providing default value
var {a: aa = 10, b: bb = 5} = {a: 3};
console.log(aa); // 3
console.log(bb); // 5
// Setting a function parameter's default value
/*
* 函数签名中,解构的左手边被分配给右手边的空对象字面值:
* {size = 'big', cords = {x: 0, y: 0}, radius = 25} = {}
* 也可以在没有右侧分配的情况下编写函数。
* 但是,如果你忽略了右边的赋值,那么函数会在被调用的时候查找至少一个被提供的参数
* 否则会报错:TypeError: Cannot destructure property `a` of 'undefined' or 'null'.
*/
function func({a = 'big', b = {x: 0, y: 0}, c = 25} = {}) {
console.log(a, b, c);
// do something
}
func(); // 'big' {x: 0, y: 0} 25
/* Another Pattern */
function move({x, y} = { x: 0, y: 0 }) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]
// undefined will be destructured using default value
[1, undefined, 3].map((x = 'yes') => x);
// [ 1, 'yes', 3 ]
// Nested object and array destructuring(解构嵌套对象和数组)
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"
// For of iteration and destructuring
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"
// Computed object property names and destructuring
let key = 'z';
let {[key]: foo} = {z: 'bar'};
console.log(foo); // "bar"
// Rest in Object destructuring
let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
a; // 10
b; // 20
rest; // { c: 30, d: 40 }
// Existing Object destructuring
let { log, sin, cos, PI } = Math;
sin(PI/2); // 1
// Object destructuring via Array
let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;
console.log(first) // 1
console.log(last) // 3
// String is converted into a array-like object
const [a, b] = 'he';
a // "h"
b // "e"
// using its length property to destructure
let {length : len} = 'hello';
len // 5
let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true
let { prop: x } = undefined; // TypeError: Cannot destructure property `prop` of 'undefined' or 'null'.
let { prop: y } = null; // TypeError: Cannot destructure property `prop` of 'undefined' or 'null'.
可以使用圆括号的情况只有一种:赋值语句的非模式部分
// 全部报错
let [(a)] = [1];
let {x: (c)} = {};
let ({x: c}) = {};
let {(x: c)} = {};
let {(x): c} = {};
let { o: ({ p: p }) } = { o: { p: 2 } };
函数参数也属于变量声明,因此不能带有圆括号。
// 报错
function f([(z)]) { return z; }
// 报错
function f([z,(x)]) { return x; }
// 全部报错
({ p: a }) = { p: 42 };
([a]) = [5];
// 报错
[({ p: a }), { x: c }] = [{}, {}];