ES6笔记 -- 解构赋值
变量的解构赋值
其核心规则为: 只要右边的值不是对象或数组, 就会先将其转为对象, 而null
和undefined
不是对象, 所以不能解构赋值
数组的结构赋值
基本用法
- 匹配语法为
let [a, b, c] = ['a', 'b', 'c']
- 匹配规则为从左到右一一配对
- 如果等式左边元素多于右边元素, 则多出来的元素值为
undefined
, 这种情况被称为解构失败 - 如果等式右边元素多于左边元素, 则左边元素只会匹配相应的(根据规则匹配↑)元素, 这种情况被称为不完全解构
- 只要具备 Iterartor 接口, 即可使用该数组形式的结构赋值
默认值
-
默认值的设定方法为
let [x = 'a', y] = ['x'] // 根据规则匹配结果为x = x, y = undefined
-
赋值的值为
undefined
时, 不会覆盖默认值let[x = 'x'] = [undefined] // x
-
如果默认值为表达式, 那么这个表达式是惰性求值的, 只有在用到的时候才会求值
-
默认值取值也可以为其他变量, 前提是, 该变量已经声明
对象的解构赋值
-
语法:
let {foo:foo, bar:bar} = {foo: 'aaa', bar:'bbb'}
-
与数组解构不同的是, 其取值不按照顺序, 而是根据相同的属性名取值
-
特殊写法为(参见对象扩展一节):
let {foo, bar} = {foo: ‘aaa’, bar: ‘bbb’}
,这种情况下foo
相当于foo:'foo'
-
注意, 这种解构法变量的声明和赋值是连续进行的, 而
let
和const
不允许重新声明, 如果需在let
或const
声明后解构赋值,则遵循以下规则- 只能在第一次声明时使用
let
- 解构赋值时需要在括号内进行, 这是因为大括号理解为代码块而不是赋值语句(参见圆括号一节)
let x ({x:y} = {x:'233'}) // y: 233
- 只能在第一次声明时使用
-
对象解构也可以设置默认值, 其设置方法与数组类似, 具体可查阅文档
-
嵌套时, 父属性不能声明赋值时, 将会报错, 对比
// 报错, 这里相当于 /* *let baz = {bar: 'baz'} *console.log(foo.bar) */ let {foo: {bar: 'baz'}} = {baz: {bar: 'baz'}} // 这里相当于 foo 解构失败, 结果为undefined let {foo} = {baz: {bar: 'baz'}}
-
应用场景:
- 对象解构可以很方便将现有对象的方法赋值到某个变量上, 如
let {log, sin:Sin, cos: Cos} = Math // 此时 log, Sin, Cos 对应 Math 相应的方法
-
对数组(特殊的对象)进行解构
let arr = [1, 2, 3] // 以下的对象写法参见对象扩展一节 let {0: first} = arr // first: 1
字符串的解构赋值
-
由于基本包装类型字符串与数组类似, 所以解构结果与数组相似
const [a, b, c, d, e] = 'hello'
-
类似的, 也可以获取到其长度属性
len {length: len} = 'hello' // len: 5
数值和布尔值的解构赋值
- 解构赋值时, 如果等号右边是数值和布尔值, 则会先转为对象
函数参数的解构赋值
-
参数使用解构赋值的例子为:
[[1, 2], [3, 4]].map(([a, b]) => a + b) // [3, 7]
-
函数参数的解构也可以使用默认值, 但有种特殊情况需要注意
function move ({x, y} = {x:0, y: 0}) { return [x, y] } move({x: 3, y: 8}) //[ 3, 8] // 这是因为此时指定的默认值是 move 的参数而不是参数里的单个变量 move({x: 3}) // [3, undefined] move() // [0, 0]
-
一般使用默认值, 是为了防止传入的参数为
undefined
圆括号
由于圆括号的使用会存在一系列问题, 所以尽量不使用圆括号
不能使用圆括号的场景
- 声明语句
- 函数的形参参数部分
- 赋值语句
- 赋值语句中, 等式左边整个模式
- 赋值语句中, 等式左边嵌套模式的某一层
- 以上两点总结就是, 等式左边的圆括号不能套在
[]
或{}
外面
能使用圆括号的场景
- 赋值语句且等式左边非模式(即[]或{}内部)部分
用途
- 交换变量的值
[x, y] = [y, x]
- 函数返回多个值
// 返回数组, 对象方法类似
function foo () {
return [1, 2, 3]
}
let [a, b, c] = foo()
-
函数参数定义
// 此时函数内可以直接使用x, y, z变量, 对象方法类似 function f([x, y, z]) {} f([1, 2, 3])
-
JSON 数据的提取
let jsonData = { id: 23, statusCode: 200, data: [867,248] } let {id, status, data: number} = jsonData
-
函数参数值的默认值(写封装的时候尤其适合, 例子略)
-
遍历 Map 结构(暂时没学, 下次补充)
-
输入模块的指定方法
const {getId} = require("./getId")