通过解构赋值destructuring assignment表达式,你能够将数组中的元素或者对象的属性直接取出来赋值给变量。
目录
一、语法:
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}
二、描述:
对象和数组的字面表达式({}、[])提供了一个临时保存数据集合的简便方法。
var x = [1, 2, 3, 4, 5];
解构赋值采用的语法与上述代码相似,只是在赋值语句的左侧来定义需要从数据集合中取哪些值。
var x = [1, 2, 3, 4, 5]; var [y, z] = x; console.log(y); // 1 console.log(z); // 2
诸如Perl、Python这样的编程语言中,也有类似的特性。
三、数组解构
2.1、基本的变量赋值
var foo = ['one', 'two', 'three']; var [one, two, three] = foo; console.log(one); // "one" console.log(two); // "two" console.log(three); // "three"
2.2、变量赋值与声明分开
var a, b; [a, b] = [1, 2]; console.log(a); // 1 console.log(b); // 2
2.3、默认值
解构赋值可以指定默认值,这个默认值会在取到的值为undefined时生效。
var a, b; [a=5, b=7] = [1]; console.log(a); // 1 console.log(b); // 7
2.4、变量交换
交换变量值的操作可以直接在一个解构赋值语句中实现了,不需要再临时声明一个变量用来存值了。
var a = 1; var b = 3; [a, b] = [b, a]; console.log(a); // 3 console.log(b); // 1
2.5、解析函数返回的数组
函数直接返回数组的情况是很常见的。借助解构赋值,可以让处理函数的数组返回值的代码更精炼。
在下面这个例子里,f()会返回数组[1, 2],通过解构赋值,只需要一行代码就可以解析这个数组了。
function f() { return [1, 2]; } var a, b; [a, b] = f(); console.log(a); // 1 console.log(b); // 2
2.6、忽略部分返回值
如果数组中有一些返回值是你不感兴趣的,可以通过类似下面这样的代码予以忽略:
function f() { return [1, 2, 3]; } var [a, , b] = f(); console.log(a); // 1 console.log(b); // 3
你也可以忽略所有的返回值(不过讲道理,这代码有啥用?):
[,,] = f();
2.7、将数组中剩余元素赋值给一个变量
var [a, ...b] = [1, 2, 3]; console.log(a); // 1 console.log(b); // [2, 3]
注意,如果在上述代码中…b右边加上逗号的话,是会报错的。
2.8、从正则匹配结果中取值
通过正则表达式的exec()方法,你会得到一个这样的数组[正则完整匹配的字符串, 正则中第一个括号内表达式所匹配的字符串, 正则中第二个括号内表达式所匹配的字符串, …, 正则中最后一个括号内表达式所匹配的字符串],通过解构,你能更方便的取你想要的值。
var url = 'https://developer.mozilla.org/en-US/Web/JavaScript'; var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url); console.log(parsedURL); // ["https://developer.mozilla.org/en-US/Web/JavaScript", "https", "developer.mozilla.org", "en-US/Web/JavaScript"] var [, protocol, fullhost, fullpath] = parsedURL; console.log(protocol); // "https"
四、对象解构
3.1、基本的变量赋值
var o = {p: 42, q: true}; var {p, q} = o; console.log(p); // 42 console.log(q); // true
3.2、变量声明与赋值分开
var a, b; ({a, b} = {a: 1, b: 2});
说明:
- 在对对象字面量解构赋值时,若不是同时进行变量声明的话,解构赋值语句两侧的括号是需要的。
- 从语法上来说,单独{a, b} = {a: 1, b: 2}这样的代码并不是有效的代码,因为等号左侧的{a, b}会被当作块级表达式而非对象字面量。
- 不过,({a, b} = {a: 1, b: 2})这样的代码就跟var {a, b} = {a: 1, b: 2}一样,都是有效的。
- 提醒:如果你的解构赋值代码(…)的上一行是一个函数,你可能需要在你的(…)解构赋值代码前加一个分号,不然可能就直接执行调上一行的函数了-_-。
3.3、赋值给新的变量名
var o = {p: 42, q: true}; var {p: foo, q: bar} = o; console.log(foo); // 42 console.log(bar); // true
3.4、默认值
可以对对象进行解构赋值时指定默认值,当解构出来的值为undefined时,就会使用默认值。
var {a = 10, b = 5} = {a: 3}; console.log(a); // 3 console.log(b); // 5
3.5、设定函数入参的默认值
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 });
3.6、嵌套对象/数组解构
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"
3.7、for of遍历和解构
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"
3.8、从函数的对象类型入参中取字段
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"
3.9、对象的计算属性与解构
let key = 'z'; let {[key]: foo} = {z: 'bar'}; console.log(foo); // "bar"
3.10、将对象的剩余属性赋值给一个变量
let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40} a; // 10 b; // 20 rest; // { c: 30, d: 40 }
3.11、无效的JS identifier作为对象属性名
const foo = { 'fizz-buzz': true }; const { 'fizz-buzz': fizzBuzz } = foo; console.log(fizzBuzz); // "true"
参考:
- https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment