@xiaoyixy
2018-11-08T09:06:07.000000Z
字数 4337
阅读 1390
Note ES6 ECMAScript6
解构赋值语法是一个 Javascript 表达式,这使得可以将值从数组或属性从对象提取到不同的变量中。
var a, b, rest;[a, b] = [10, 20];console.log(a); // 10console.log(b); // 20[a, b, ...rest] = [10, 20, 30, 40, 50];console.log(a); // 10console.log(b); // 20console.log(rest); // [30, 40, 50]({ a, b } = { a: 10, b: 20 });console.log(a); // 10console.log(b); // 20// Stage 3 proposal({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});console.log(a); // 10console.log(b); // 20console.log(rest); //{c: 30, d: 40}
// Basic variable assignmentvar foo = ['one', 'two', 'three'];var [one, two, three] = foo;console.log(one); // "one"console.log(two); // "two"console.log(three); // "three"// Assignment separate from declarationvar a, b;[a, b] = [1, 2];console.log(a); // 1console.log(b); // 2// Default valuesvar a, b;[a=5, b=7] = [1];console.log(a); // 1console.log(b); // 7// Swapping variablesvar a = 1;var b = 3;[a, b] = [b, a];console.log(a); // 3console.log(b); // 1// Ignoring some returned valuesfunction f() {return [1, 2, 3];}var [a, , b] = f();console.log(a); // 1console.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); // 1console.log(b); // [2, 3]// 剩余元素必须是数组的最后一个元素var [a, ...b,] = [1, 2, 3];// SyntaxError: rest element may not have a trailing comma
// Basic assignmentSectionvar o = {p: 42, q: true};var {p, q} = o;console.log(p); // 42console.log(q); // true
// Assignment without declarationSectionvar 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 namesvar o = {p: 42, q: true};var {p: foo, q: bar} = o;console.log(foo); // 42console.log(bar); // true
// Default valuesvar {a = 10, b = 5} = {a: 3};console.log(a); // 3console.log(b); // 5
// Assigning to new variables names and providing default valuevar {a: aa = 10, b: bb = 5} = {a: 3};console.log(aa); // 3console.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 destructuringvar 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 destructuringlet key = 'z';let {[key]: foo} = {z: 'bar'};console.log(foo); // "bar"
// Rest in Object destructuringlet {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}a; // 10b; // 20rest; // { c: 30, d: 40 }
// Existing Object destructuringlet { log, sin, cos, PI } = Math;sin(PI/2); // 1
// Object destructuring via Arraylet arr = [1, 2, 3];let {0 : first, [arr.length - 1] : last} = arr;console.log(first) // 1console.log(last) // 3
// String is converted into a array-like objectconst [a, b] = 'he';a // "h"b // "e"// using its length property to destructurelet {length : len} = 'hello';len // 5
let {toString: s} = 123;s === Number.prototype.toString // truelet {toString: s} = true;s === Boolean.prototype.toString // truelet { 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 }] = [{}, {}];