变量的解构赋值
数组的结构赋值
let [a, [[b], c]] = [1, [[2], 3]];
console.log(a, b , c); // 1 2 3
let [a, , c] = [1, 2, 3];
console.log(a, c); // 1 3
let [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]
let [a, b, ...c] = [1];
console.log(a); // 1
console.log(b); // undefined
console.log(c); // []
如果右边不是数组(不是可遍历的结构),解构会报错。
let [a] = null; // Uncaught TypeError: null is not iterable
let [a] = undefined; // Uncaught TypeError: undefined is not iterable
let [a] = false; // Uncaught TypeError: false is not iterable
let [a] = 1; // Uncaught TypeError: 1 is not iterable
let [a] = {}; // Uncaught TypeError: {} is not iterable
Set 结构也可以使用数组的解构赋值。
let [a] = new Set([1, 2, 3]);
console.log(a); // 1
只要有 Iterator 接口,都可以用数组的结构赋值。
function* fibs() {
let a = 0;
let b = 1;
console.log(a, b); // 0 1
while (true) {
yield a;
[a, b] = [b, a + b];
console.log(a, b);
}
}
let [first, second, third, fourth, fifth, sixth] = fibs();
默认值
可以指定默认值。
let [a = true] = [];
console.log(a); // true
let [a, b = 2] = [1];
console.log(a, b); // 1 2
let [a, b = 2] = [1, undefined];
console.log(a, b); // 1 2
当数组成员严格等于 undefined,默认值才会生效。
let [a] = [null];
console.log(a); // null
如果默认值是表达式,这个表达式是惰性求值的,只有用到时,才会求值。
function f() {
console.log('a');
return 'a';
}
let [a = f()] = [1];
console.log(a); // 1 注意 f() 不会执行
对象的解构赋值
let { a, b } = {a: 1, b: 2};
console.log(a, b); // 1 2
数组的解构是按顺序排列的,但是对象的解构没有顺序,变量名需与属性名相同,才能取到正确的值。
let { c } = {a: 1, b: 2};
console.log(c); // undefined
将现有对象的方法赋值给某个变量。
let { log } = console;
log('test'); // test
let { sin, cos } = Math;
console.log(sin(0), cos(0)); // 0, 1
变量名与属性名不一样。
let { a: b } = { a: 1 };
console.log(b); // 1
对象的解构也可以是嵌套的。
let obj = {
a: [
'Hello',
{
y: 'world',
},
],
};
let { a: [x, { y } ] } = obj;
console.log(x, y); // Hello world
嵌套赋值
let obj = {};
let arr = [];
({ a: obj.a, b: arr[0] } = { a: 1, b: 2 });
console.log(obj); // {a: 1}
console.log(arr); // [2]
默认值
let { a = 1 } = {};
console.log(a); // 1
注意点
将已经声明的变量用于解构赋值,大括号不能位于行首。
// 会报错
let x;
{ x } = { x: 1}; // Uncaught SyntaxError: Unexpected token =
// 用括号括起来
let x;
({ x } = { x: 1});
可以对数组进行对象属性的解构。
const { length } = [1, 2, 3];
console.log(length); // 3
字符串的解构赋值
字符串可以解构赋值,是因为字符串被转换为类似数组的对象。
const [ a, b, c, d ] = '123456';
console.log(a, b, c, d); // 1 2 3 4
const { length } = '123456';
console.log(length); // 6
数值和布尔值的解构赋值
先将数值和布尔值转换为对象,再进行解构赋值。
如果右边是 null 和 undefined,因为无法转换为对象,所以对它们解构赋值会报错。
函数参数的解构赋值
function add([a, b]) {
console.log(a + b);
}
add([1, 2]); // 3
用途
1、交换变量的值
let x = 1;
let y = 2;
[x, y] = [y, x];
console.log(x, y); // 2 1
2、从函数返回多个值
// 返回一个数组
function f() {
return [1, 2, 3];
}
const [a, b, c] = f();
console.log(a, b, c); // 1 2 3
// 返回一个对象
function f() {
return {
a: 1,
b: 2,
};
}
const {a, b} = f();
console.log(a, b); // 1 2
3、函数参数的定义
// 有序的值
function f([a, b, c]) {
// ...
}
f([1, 2, 3]);
// 无序的值
function f({a, b, c}) {
// ...
}
f({c: 3, a: 1, b: 2});
4、提取 JSON 数据
const json = {
name: 'name',
age: 21,
country: 'china',
};
const { name, age, country } = json;
5、函数参数的默认值
const fn = ({
a: 1,
b: 2
} = {}) => {
// ...
}
6、遍历 Map 结构
const map = new Map();
map.set('first', 'Hello');
map.set('second', 'world');
for (let [key, val] of map) {
console.log(`${key} is ${val}.`);
}
// first is Hello.
// second is world.
7、输入模块的指定方法