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);
}