目录
- 数组解构
- 对象解构
- 字符串解构
- 数值和布尔值解构
- 函数参数解构
- 圆括号问题
- 用途
数组解构
'' let [foo, [[bar], baz]] = [1, [[2], 3]]; // 1 2 3
'' let [ , , third] = ["foo", "bar", "baz"]; // baz
'' let [x, , y] = [1, 2, 3]; // 1 3
'' let [head, ...tail] = [1, 2, 3, 4]; // 1 [2,3,4]
'' let [x, y, ...z] = ['a']; // a undefined []
特性
本质上属于”匹配模式“,等号两边模式相同,左边的变量被赋予对应的值
TS 对该语法进行优化使之兼容 ES5 环境,底层原理在编译时遍历右侧对象属性赋值到左侧遍历(不同场景有不同表现),通常仅处理使用到的属性
如果解构失败赋值 undefined
场景
需要操作复杂对象(数组、对象)的属性时
默认值
'' let [foo = true] = [];
'' let [x, y = 'b'] = ['a']; // x='a', y='b'
'' let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
解构赋值运行有默认值,ES6 内部使用严格相等运算符(===),判断是否等于undefined
,默认值才会生效
默认值是惰性求值,如果该默认值不会生效,默认值不会被执行
对象解构
特性
'' let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
'' foo // "aaa"
'' bar // "bbb"
对象解构与数组解构类似,差异在于数组根据顺序,变量可以随便命名。对象必须严格按照属性名,可以打乱顺序
'' let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
'' baz // "aaa"
变量名和属性名不一致可采用这种写法
'' let arr = [1, 2, 3];
'' let {0 : first, [arr.length - 1] : last} = arr;
'' first // 1
'' last // 3
数组是一种特殊的JS对象,因此也可以对数组采用对象解构方式
场景
字符串解构
特性
'' const [a, b, c, d, e] = 'hello';
'' a // "h"
'' b // "e"
'' c // "l"
'' d // "l"
'' e // "o"
字符串可以解构为类似数组的对象
'' let {length : len} = 'hello';
'' len // 5
类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值
场景
数值和布尔值解构
特性
'' let {toString: s} = 123;
'' s === Number.prototype.toString // true
''
'' let {toString: s} = true;
'' s === Boolean.prototype.toString // true
数值和布尔值解构时会先转为对象
场景
函数解构参数解构
特性
'' function add([x, y]){
'' [[1, 2], [3, 4]].map(([a, b]) => a + b); // [ 3, 7 ]
场景
用途
变量交换 [x, y] = [y, x];
从函数返回多个值 return [1, 2, 3];
函数参数的定义function f([x, y, z]) { ... }
提取 JSON let { id, status, data: number } = jsonData;
遍历 Map 结构for (let [key, value] of map) {
for (let [key] of map) {
for (let [,value] of map) {
导入模块 const { SourceMapConsumer, SourceNode } = require("source-map");