const a = 1 const b = 2 // 可以写成这样 const [a, b] = [1, 2]
只要等号两边的模式相同,左边的变量就会被赋予对应的值
// 使用嵌套数组进行解构 const [foo, [[bar], baz]] = [1, [[2], 3]] foo // 1 bar // 2 baz // 3
如果解构不成功,变量的值就等于 undefined
。
let [x, y, ...z] = ['a'] x // "a" y // undefined z // []
有一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。
let [a, [b], d] = [1, [2, 3], 4] a // 1 b // 2 d // 4
如果等号的右边不是可遍历的结构,那么将会报错。只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。
如果一个数组成员不严格等于 undefined
,默认值是不会生效的
var [foo = true] = [] foo // true [x, y = 'b'] = ['a'] // x='a', y='b' [x, y = 'b'] = ['a', undefined] // x='a', y='b' [x, y = 'b'] = ['a', null] // x='a', y=null
默认值可以引用解构赋值的其他变量,但该变量必须已经声明。
var { foo, bar } = { foo: "aaa", bar: "bbb" } foo // "aaa" bar // "bbb"
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
如果变量名跟属性名不一致,必须写成下面的形式
var { bar, foo } = { foo: "aaa", bar: "bbb" } foo // "aaa" bar // "bbb" var { baz } = { foo: "aaa", bar: "bbb" } baz // undefined
对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
var obj = { p: [ 'Hello', { y: 'World' } ] } var { p: [x, { y }] } = obj x // "Hello" y // "World"
对象的解构也可以指定默认值,默认值生效的条件也是对象的属性值严格等于 undefined
var {x = 3} = {} x // 3
如果解构失败,变量的值等于 undefined
var {foo} = {bar: 'baz'} foo // undefined
如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。
var {foo: {bar}} = {baz: 'baz'}
字符串也是可以解构赋值的,因为此时,字符串被转换成了一个类似数组的对象。
var [a, b] = 'hello' a // "h" b // "e"
解构赋值的规则是,只要等号右边的值不是对象,就先将其转为对象。由于 undefined
和 null
无法转为对象,所以对它们进行解构赋值,都会报错。
var {toString: s} = 123 s === Number.prototype.toString // true var {toString: s} = true s === Boolean.prototype.toString // true
[[1, 2], [3, 4]].map(([a, b]) => a + b) // [ 3, 7 ]
以下三种解构赋值不得使用圆括号
(1)变量语句中,不能带有圆括号
// 全部报错 var [(a)] = [1] var {x: (c)} = {} var ({x: c}) = {} var {(x: c)} = {} var {(x): c} = {} var { o: ({ p: p }) } = { o: { p: 2 } }
(2)函数参数中,模式不能带有圆括号
// 报错 function f([(z)]){ return z }
(3)赋值语句中,不能将整个模式,或嵌套模式中的一层,放在圆括号之中
// 全部报错 ({ p: a }) = { p: 42 } ([a]) = [5]
可以使用圆括号的情况只有一种:赋值语句的非模式部分,可以使用圆括号
[(b)] = [3]; // 正确 ({ p: (d) } = {}); // 正确 [(parseInt.prop)] = [3]; // 正确
(1)交换变量的值
[x, y] = [y, x]
(2)从函数返回多个值
函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回
function example(){ return [1, 2, 3] } var [a, b, c] = example()
(3)函数参数的定义
// 参数是一组有次序的值 function f([x, y, z]){ ... } f([1, 2, 3]) // 参数是一组无次序的值 function f({x, y, z}){ ... } f({z: 3, y: 2, x: 1})
(4)函数参数默认值
jQuery.ajax = function (url, { async = true, beforeSend = function () {}, cache = true, complete = function (){}, crossDomain = false, global = true, // ... more config }) { // ... do stuff }
(5)遍历 Map 结构
for (let [key, value] of map) { alert(key + value); }