数组
- 从数组中提取值,按照位置对变量赋值。只要等号两边的模式相同,左边的变量就会被赋予对应的值。如果解构不成功,变量的值为
undefined。
- 只要某种数据结构具有
Iterator接口,都可以采用数组形式的解构赋值。
let [a, b, c] = [1, 2, 3];
a
b
c
let [foo, [[bar], baz]] = [1, [[2], 3]];
foo
bar
baz
let [ , , third] = ["foo", "bar", "baz"];
third
let [x, , y] = [1, 2, 3];
x
y
let [head, ...tail] = [1, 2, 3, 4];
head
tail
let [x, y, ...z] = ['a'];
x
y
z
- 如果等号右边的不是数组(是不可遍历的结构),那么将会报错。
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
let [x, y, z] = new Set(['a', 'b', 'c']);
x
默认值
- 内部使用严格相等
===来判断一个位置是否有值。只有当一个数组成员===undefined,默认值才会生效。
let [foo = true] = [];
foo
let [x, y = 'b'] = ['a'];
y
let [x, y = 'b'] = ['a', undefined];
y
let [x = 1] = [null];
x
- 如果默认值是一个表达式,那么这个表达式是惰性求值的。当只有用到的时候才会求值。
function f(){
return 'b';
}
let [a = f()] = [1];
a
let [b = f()] = [];
b
- 默认值可以引用解构赋值的其他变量,前提是该变量已经声明。
let [x = 1, y = x] = [];
let [x = 1, y = x] = [2];
let [x = y, y = 1] = [];
对象
- 与数组解构赋值不同,数组是按照位置的对等进行的,而对象的属性没有次序,变量必须与
属性同名,才能取到正确的值。如果解构不成功,变量的值为undefined。
let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };
let { bar, foo } = { foo: 'aaa', bar: 'bbb' };
foo
bar
let { baz } = { foo: 'aaa', bar: 'bbb' };
baz
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x;
y;
z;
const node = {loc: { start: { line: 1, column: 5 }}};
const {loc, loc: {start}, loc: {start:{line}}} = node;
loc
start
line
- 对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
foo
baz
- 对象的解构赋值可以很方便的将现有对象的方法赋值到某个变量。
let { log, sin, cos } = Math;
const { log } = console;
log('hello!');
默认值
- 默认值生效的条件是,对象的属性值严格等于
undefined。
let {x = 3} = {};
x
let {x, y = 5} = {x: 1};
x
y
let {x: y = 3} = {};
y
let {x: y = 3} = {x: 5};
y
let {msg: msg = 'sb'} = {};
msg
字符串
const [a, b, c, d, e, f = '!'] = 'hello';
a
b
c
d
e
f
let {length: len} = 'hello';
len
数值和布尔
- 只要等号右边的值不是对象或数组,就先将其转为对象。
let {toString: s} = 123;
s === Number.prototype.toString
let {toString: s} = true;
s === Boolean.prototype.toString
let { prop: x } = undefined;
let { prop: y } = null;
函数参数
function add([x, y]){
return x + y;
}
add([1, 2]);
function move({x = 0, y = 0} = {}) {
return [x, y];
}
move({x: 3, y: 8});
move({x: 3});
move({});
move();
function move({x, y} = { x: 0, y: 0 }) {
return [x, y];
}
move({x: 3, y: 8});
move({x: 3});
move({});
move();
用途
交换变量的值
let x = 1;
let y = 2;
[x, y] = [y, x];
x
y
从函数返回多个值
- 函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象中返回。可以用解构赋值,一次取出多个值。
function example() {
return {
foo: 1,
bar: 2
};
}
let { foo, bar } = example();
提取JSON数据
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number);
函数参数的默认值
- 避免了函数体内部再写
var foo = config.foo || 'default foo';
function request(url, {method = 'GET', loading = true, callback = function(){}})
遍历Map结构
const map = new Map();
map.set('first', 'hello');
map.set('second', 'world');
for (let [key, value] of map) {
console.log(key + " is " + value);
}
for (let [key] of map){...}
for (let [, value] of map){...}
加载模块的指定方法
const { getUserInfo, login } = require("source-map");