JavaScript|解构赋值

基本概念

JS中最常使用的数据类型是对象以及数组

但是有的时候我们实际上并不需要一个对象中所有的字段,或者说数组中所有的数据

因此ES6中引入了解构赋值这一操作来将对象或者数组拆解结构并赋值到新的多个变量上

数组解构

基本声明

1
let [firstName, surName] = 'John Smith'.split(' ');
1
let [firstName, surName] = ['John', 'Smith'];
1
2
3
let arr = ['John', 'Smith'];
let firstName = arr[0];
let surName = arr[1];

以上三种形式效果等价,前两种就是数组的解构赋值

忽略元素

可以在等号左边通过逗号来忽略元素

1
2
let [a,,c] = [1,2,3];
alert(c); //3

等号右侧适用于任何可迭代的数组

数组解构可以解构通用的数组,但并不局限,也可以解构任何可迭代的数组,例如字符串

1
let [a,b,c] = "123";

等号左侧适用于任何可赋值的元素

1
2
let user = {};
[user.firstName, user.surName] = 'John Smith'.split(' ');

获取数组剩下的元素

通常我们想要的数据远比对象/数组本身提供的少,我们可以通过...的方式来收集剩余的项

1
2
3
4
5
let [name1, name2, ...rest] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
// rest 是包含从第三项开始的其余数组项的数组
alert(rest[0]); // Consul
alert(rest[1]); // of the Roman Republic
alert(rest.length); // 2

默认值

一般是左边更短右边更长

如果左边更长的话不会报错,只是未被按顺序赋值到的元素都是undefined

我们可以通过在解构赋值的表达式中定义等号来声明默认值

1
let [foo, bar = 'default bar'] = ["foo"];

对象解构

对象解构的方式比较直接,就是将需要的对象key单独声明在左边列表即可

1
2
3
4
5
6
7
let options = {
title: "Menu",
width: 100,
height: 200
}

let {title, width, height} = options;

在左侧被赋值的变量上起别名也是可以的,通过冒号声明,冒号的语法是“从对象中什么属性的值:赋值给哪个变量”

1
let {title:t, width:w, height:h} = options;

类似数组解构,如果可能缺失的值,也可以通过等号进行默认值填充

1
let {title:t, width:w, height:h, number = 10} = options;

同样也支持...将剩余的数据收集

1
let {title, ...rest} = options;

对象解构时使用已有变量的问题

1
2
3
4
let title, width, height;

// 这一行发生了错误
{title, width, height} = {title: "Menu", width: 200, height: 100};

由于对象解构采用的是{},因此上述的声明会被js误认为是一段代码块

1
2
3
4
5
{
title,
width,
height
}

显然这种声明是非法的

为了不让js误判代码块,让他知道我们这是对象解构复用已有变量,需要多包上一层小括号

1
({title, width, height} = {title: "Menu", width: 200, height: 100});

嵌套解构

本质上可以看作是对象解构和数组解构的综合运用

只要让等式左边和右边数据类型对应上即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let options = {
size: {
width: 100,
height: 200
},
items: ["Cake", "Donut"],
extra: true
};

let {
size: { // 把 size 赋值到这里
width,
height
},
items: [item1, item2], // 把 items 赋值到这里
title = "Menu" // 在对象中不存在(使用默认值)
} = options;

alert(title); // Menu
alert(width); // 100
alert(height); // 200
alert(item1); // Cake
alert(item2); // Donut

函数入参解构赋值

有的时候我们的函数入参可能不需要那么多,大部分参数是可选的,也就是不需要手动传入

换成别的语言可能会这么写

1
2
3
function showMenu(title = "Untitled", width = 200, height = 100, items = []) {
// ...
}
1
showMenu("My Menu", undefined, undefined, ["Item1", "Item2"])

这种方式可行,但是代码有点差

我们可以使用对象作为函数入参,函数签名处使用解构赋值,拆分对象属性,自动定义变量以及默认值,在函数体内直接单独挑出来使用,可以完美解决上述问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
let params = {
title: 'Menu',
width: 100,
height: 200,
};

function showMenu({
title = 'Untitled',
width = 200,
height = 100,
items = [],
}) {
alert(`${title} ${width} ${height}`); // My Menu 200 100
}

showMenu(params);
}

此时,由于items没有被指定,因此就是使用的默认值空数组,剩下的都将根据真实值传递而非使用默认值

但是这样还有一个问题,就是如果我们都直接打算使用默认值,不能不定义,一定要手动传入一个空对象

1
showMenu({});

为了避免这种冗余的声明,我们可以在函数参数声明的地方定义默认值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
let params = {
title: 'Menu',
width: 100,
height: 200,
};

function showMenu({
title = 'Untitled',
width = 200,
height = 100,
items = [],
} = {}) {
alert(`${title} ${width} ${height}`); // My Menu 200 100
}

showMenu(params);
//全部使用默认值
showMenu();
}

JavaScript|解构赋值
http://example.com/2025/03/03/JavaScript-解构赋值/
作者
Noctis64
发布于
2025年3月3日
许可协议