- 变量的解构赋值
- 数组的解构赋值
- 对象解构赋值
- 对象的解构与数组有一个重要的不同。
- 嵌套结构的对象
- 字符串的解构赋值
- 数值和布尔值的解构赋值
- 函数参数的解构赋值
- 变量的解构赋值用途
- 交换变量的值
- 从函数返回多个值
- 函数参数的定义
- 提取JSON数据
- 设置默认值
- 遍历Map和Set
- 不完全解构
- 输入模块的指定方法
1. 变量的解构赋值
ES6(ECMAScript 2015)中的变量解构赋值是一种允许你按照一定的模式,从数组或者对象中直接提取值并赋给变量的特性。这种机制简化了数据处理,使得代码更加简洁易读。
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这
被称为解构(Destructuring)。
1.1. 数组的解构赋值
可以从数组中提取值,按照对应位置,对变量赋值。
本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。
下面是一些使用嵌套数组进行解构的例子。
let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3
let [ , , third] = ["foo","bar","baz"];
third // "baz"
let [x, , y] = [1, 2, 3];
x // 1
y // 3
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []
如果解构不成功,变量的值就等于 undefined 。
let [foo] = [];
let [bar, foo] = [1];
1.2. 对象解构赋值
let { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
1.2.1. 对象的解构与数组有一个重要的不同。
- 数组的元素是按次序排列的,变量的取值由它的位置决定;
- 对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
let { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined
上面代码的第一个例子,等号左边的两个变量的次序,与等号右边两个同名属性的次序不一致,但是对取值完全没有影响。
第二个例子的变量没有对应的同名属性,导致取不到值,最后等于 undefined 。
对象的解构赋值是下面形式的简写。
let { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };
1.2.2. 嵌套结构的对象
let obj = {
p: [
'Hello',
{ y: 'World' }
]
};
let { p: [x, { y }] } = obj;
x // "Hello"
y // "World"
1.3. 字符串的解构赋值
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象
。
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
类似数组的对象都有一个 length 属性,因此还可以对这个属性解构赋值。
let {length : len} = 'hello';
len // 5
1.4. 数值和布尔值的解构赋值
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。
let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true
上面代码中,数值和布尔值的包装对象都有 toString 属性,因此变量 s 都能取到值。
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。
由于 undefined 和 null 无法转为对象,所以对它们进行解构赋值,都会报错。
let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError
1.5. 函数参数的解构赋值
函数的参数也可以使用解构赋值
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
[[1, 2], [3, 4]].map(([a, b]) => a + b);
// [ 3, 7 ]
// 使用默认值
function move({x = 0, y = 0} = {}) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]
2. 变量的解构赋值用途
变量的解构赋值在ES6中引入,它提供了一种更简洁、更直观的方式来处理数组和对象的数据,以下是其主要用途及示例:
2.1. 交换变量的值
不需要临时变量即可交换两个变量的值。
let x = 1, y = 2;
[x, y] = [y, x];
console.log(x); // 输出: 2
console.log(y); // 输出: 1
2.2. 从函数返回多个值
函数可以返回一个包含多个值的数组或对象,解构赋值可以直接提取这些值。
function getCoordinates() {
return [10, 20];
}
let [xCoord, yCoord] = getCoordinates();
console.log(xCoord, yCoord); // 输出: 10 20
2.3. 函数参数的定义
函数参数可以直接通过解构来定义和使用。
function sum({a, b}) {
return a + b;
}
console.log(sum({a: 3, b: 5})); // 输出: 8
2.4. 提取JSON数据
解构赋值非常适合快速提取JSON对象中的属性值。
let user = '{"name": "Alice", "sex": "famel", "age": 30}';
let {name, age} = JSON.parse(user);
console.log(name, age); // 输出: Alice 30
2.5. 设置默认值
当尝试解构的属性不存在或值为undefined
时,可以为变量设置默认值。
let options = {text: 'hello'};
let {text = 'world', size = 'large'} = options;
console.log(text, size); // 输出: hello large
2.6. 遍历Map和Set
结合迭代器,解构赋值可以方便地遍历Map和Set中的键值对或元素。
let map = new Map();
map.set('first', 'hello');
map.set('second', 'world');
for (let [key, value] of map) {
console.log(key + " is " + value);
}
// 输出: first is hello
// second is world
2.7. 不完全解构
可以仅解构数组或对象的一部分,忽略其余部分。
let [a, , b] = [1, 2, 3];
console.log(a, b); // 输出: 1 3
2.8. 输入模块的指定方法
加载模块时,往往需要指定输入哪些方法。解构赋值使得输入语句非常清晰。
const { SourceMapConsumer, SourceNode } = require("source-map");
这些用途展示了解构赋值在简化日常编程任务、提高代码效率和可读性方面的强大能力。