ES6-变量的解构赋值
数组的解构(Destructuring)赋值
基本用法
ES6允许按照一定模式从数组和对象中提取值,然后对变量进行赋值
1 | let [a, b, c] = [1, 2, 3]; |
只要等号两边模式相同,左边的变量就会被赋予对应的值
1
2
3
4
5
6
7
8let [a, [[b], c]] = [1, [[2], 3]];
console.log(a); // => 1
console.log(b); // => 2
console.log(c); // => 3
-----------------------------------------
let [a, ...b] = [1, 2, 3];
console.log(a); // => 1
console.log(b); // => [2, 3]如果解构不成功,变量的值就等于
undefined
1
2
3
4let [a, b, c] = [1, , 3];
console.log(a); // => 1
console.log(b); // => undefined
console.log(c); // => 3等号左边的模式只匹配一部分等号右边数组,此时不完全解构
1
2
3
4
5
6
7
8let [a, , c] = [1, 2, 3];
console.log(a); // => 1
console.log(c); // => 3
-----------------------------------------
let [a, [b], c] = [1, [2, 3], 4];
console.log(a); // => 1
console.log(b); // => 2
console.log(c); // => 4等号右侧不是数组(不可遍历的结构),则报错
1
2let [a, b, c] = 1;
// TypeError: undefined is not a function (near '...[a, b, c]...')
默认值
解构赋值允许指定默认值
1 | let [a = true] = []; |
ES6使用
===
判断一个位置是否有值,如果数组成员不严格等于undefined
,默认值不生效1
2
3let [a = true, b = true] = [undefined, null];
console.log(a); // => true
console.log(b); // => null如果默认值是表达式,那么这个表达式只有在用到的时候才会求值
1
2
3
4
5function f() {
console.log('asdfg');
}
let [a = f()] = [undefined]; // asdfg上面的代码等价于
1
2
3
4
5
6let a;
if ([undefined][0] === undefined) {
x = f();
} else {
x = [undefined][0];
}默认值可以引用结构赋值的其他变量,但该变量必须已经声明
1
2
3
4
5
6
7
8
9
10let [a, b = a] = [1];
console.log(a); // => 1
console.log(b); // => 1
-------------------------------------------
let [a, b = a] = [1, 2];
console.log(a); // => 1
console.log(b); // => 2
-------------------------------------------
let [a = b, b = 2] = [, 2];
// ReferenceError: Cannot access uninitialized variable.
对象的解构赋值
对象的属性没有次序,变量必须与属性同名才能取到正确的值
1 | let { a, b } = { a: 1, b: 2 }; |
实际上,上面的形式是下面形式的简写
1 | let { a: a, b: b } = { a: 1, b: 2 }; |
对象的解构赋值的内部机制:先找到同名属性,然后在赋值给对应的变量,被赋值的是后者,不是前者
1 | let { a: aa, b: b } = { a: 1, b: 2 }; |
解构也可以用于嵌套结构的对象
1 | let node = { |
如果解构失败,变量的值等于undefined
;如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那将会报错,因为此时父属性等于undefined
1 | let { a } = { b: 1 }; |
一个错误的写法:JavaScript引擎会将{x}
理解为一个代码块,可以用圆括号括起来
1 | let a; |
对数组进行对象属性的解构
1 | let array = [1, 2, 3, 4]; |
字符串的解构赋值
字符串也可以解构赋值,此时字符串被转换成了一个类似数组的对象
1 | let [a, b] = 'hi'; |
1 | let { length: len } = 'hello'; |
数值和布尔值的解构赋值
解构赋值时,如果等号右边是数值或布尔值,则会先转为对象
1 | let { toString: a } = 123; |
只要等号右边不是数组或对象,就先将其转为对象。由于undefined
和null
无法转换为对象,所以对它们进行解构赋值时都会报错
1 | let { prop: a } = undefined; |
函数的解构赋值
1 | function add([x, y]) { |
函数参数的解构也可以使用默认值
1 | function add({ x , y } = { x: 1, y: 2 }) { |
用途
交换变量的值
1 | let x = 1, y = 2; |
从函数返回多个值
1 | function f() { |
函数参数的定义
1 | function f([x, y, z]) { |
提取JSON数据
1 | let jsonData = { |
函数参数的默认值
1 | jQuery.ajax = function (url, { |
遍历map结构
1 | let map = new Map(); |
输入模块的指定方法
加载模块时,往往需要指定输入的方法。解构赋值使得输入语句非常清晰
1 | const { SourceMapConsumer, SourceNode } = require('source-map'); |