转载

ES6 - 解构

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"

数值和布尔值的解构赋值

解构赋值的规则是,只要等号右边的值不是对象,就先将其转为对象。由于 undefinednull 无法转为对象,所以对它们进行解构赋值,都会报错。

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);
}
原文  http://mertensming.github.io/2017/01/12/destructuring/
正文到此结束
Loading...