数组的解构赋值
基本用法:
ES6允许按照一定的模式从数组和对象中提取值,然后对变量进行赋值,这被称之为解构。
let [a, b, c] = [1, 2, 3];
这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。
let [foo, [[bar], baz]] = [1, [[2], [3]];
let [ , , third] = ['foo', 'bar', 'baz'];
let [x, , y] = [1, 2, 3];
let [head, ...tail] = [1, 2, 3, 4];
tail; // [2, 3, 4]
let [x, y, ...z] = ['a'];
y; // undefined
z; // []
解构不成功,变量的值等于undefine。
不完全解构:
let [a, b] = [1, 2, 3];
a; // 1
b; // 2
let [a, [b], c] = [1, [2, 3], 4];
a; // 1
b; // 2
c; // 4
如果等号右边的不是数组,则会报错。
默认值:
let [foo = true] = [];
foo; // true
ES6内部使用严格相等运算符(===)判断一个位置是否有值,所以如果一个数组不严格等于undefined,默认值是不会生效的。
let [x = 1] = [undefined];
x; // undefined
let [x = 1] = [null];
x; // null
默认值也可以是一个表达式,那么这个表达式是惰性求值的(只用在用到时才会求值)
默认值可以引用解构赋值的其他变量,但该变量必须已经声明。
对象的解构赋值
let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
foo; // 'aaa'
bar; // 'bbb'
对象的解构与数组的解构有一个重要的不同,数组的元素按次序排列,变量的取值由位置决定。而对象的属性没有次序,变量名与属性名同名则可取道正确的值。
let { abc } = { foo: 'aaa', bar: 'bbb' };
abc; // undefined
如果变量名和属性名不一致,必须写成下面这样
let { foo: abc } = { foo: 'aaa', bar: 'bbb' };
abc; // 'aaa'
实际上说明,对象的解构就是以下形式的简写:
let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };
对象的解构,首先找到同名的属性,再赋值给对应的变量。
后者被赋值,前者只是匹配模式。
对象的解构和数组的解构相同,也可用于嵌套的数据结构。
对象的解构也可以指定默认值
字符串的解构
const [a, b, c, d, e] = 'hello';
a // 'h'
b // 'e'
c // 'l'
d // 'l'
e // 'o'
//数组对象有length属性
let {length: len} = 'hello';
len // 5
数值和布尔值的解构
解构的规则是,若等号右边的值不是对象或者数组,就先转转换为对象。
let {toString: s} = 123
// 由于number和boolean对象都有toString属性,所以s能取到值
由于undefined和null无法转换为对象,所以在解构赋值时会出错。
函数参数的解构
function add([x, y]) {
return x + y
};
add([1, 2]) // 3
函数参数的解构,也可使用默认值。(undefined会触发函数的默认值)
解构的用途
- 交换变量的值
- 从函数返回多个值
- 函数参数的定义
- 提取JSON数据
- 函数参数的默认值
- 遍历map结构
- 输入模块的指定方法