在 Javascript 如何对数组和对象进行结构?下面,通过本篇文章,我们一起来探索一下 Javascript 中的解构。
定义
对于解构赋值,没有比 MDN 更简洁的定义:
解构赋值语法是一个 JavaScript 表达式,可以将数组中的值或对象中的属性解包为不同的变量。
数组解构
我们使用方括号:[]
来解构数组。
让我们看看我们可以使用解构赋值的不同场景,考虑一个包含三个元素的数组,现在你想分别用数组中的值创建三个不同的变量。旧方法是使用索引为每个新变量分配数组中的值。
const arr = [1, 2, 3];
const a = arr[0]; // a = 1
const b = arr[1]; // b = 2
const c = arr[2]; // c = 3
但是,使用解构赋值可以大大减少执行相同任务的工作量。
const arr = [1, 2, 3];
const [a, b, c] = arr;
// a = 1, b = 2, c = 3
注意:原始阵列不受影响,保持原样。只有赋值操作从左到右进行。
如果我们只需要数组中的两个元素,我们可以对两个变量使用相同的语法。数组中超过两个元素的剩余值将被丢弃。
我们也可以根据需要使用数组中该元素的空格跳过中间元素。请参阅示例以更好地理解:
const arr = [1, 2, 3, 4];
// a = 1, b = 2
const [a, b] = arr;
// x = 2, y = 4
const [ , x, , y] = arr;
使用解构交换值
传统上,我们可以使用临时变量显式交换值,然后在三个变量之间赋值和重新赋值,但现在我们可以使用解构直接赋值,示例如下:
let a = 10, b = 20;
// Old way
let temp = a;
a = b;
b = temp; // a = 20, b = 10
// Using destructuring
[a, b] = [b, a]; // a = 20, b = 10
从函数调用中接收多个值
让我们考虑一个具有很少属性的对象 restaurant
:
const restaurant = {
name: 'La\' Pinoz Pizza',
location: 'Ghaziabad',
categories: ['Italian', 'Vegetarian', 'Non-Vegetarian', 'Organic'],
starterMenu: ['Garlic Bread', 'Fries', 'Pastries'],
mainMenu: ['Pizza', 'Pasta', 'Risotto'],
order: function(starterIndex, mainIndex) {
return [this.starterMenu[starterIndex], this.mainMenu[mainIndex]];
}
}
restaurant
对象的 order 属性是一个函数,它接受两个参数并返回一个包含两个值的数组。我们可以在这里使用解构,将 Array 的元素直接赋值给变量。
const [starter, mainCourse] = restaurant.order(2,1);
console.log(starter, mainCourse);
// output: Pastries Pasta
嵌套解构
顾名思义,非常简单,在数组中解构数组。考虑一个带有嵌套数组的数组:[1, 2, [3, 4]]。当我们用这个数组分配 a,b,c 的值时,每个人都会得到分配的单个元素,即 a = 1, b = 2, c = [3,4]。如果我们想从数组 c 中分离出值,那么我们可以使用类似的解构语法并实现它。
const nested = [1, 2, [3, 4]];
const [a, b, c] = nested; // a = 1, b = 2, c = [3, 4]
const [x, , [y, z]] = nested; // x = 1, y = 3, z = 4
默认值
如果我们不知道传入数组中包含的数据,那么分配给变量的默认值是undefined
。让我们看一个例子并理解:
const unknownArray = [1, 5, 9];
const [a, b, c, d] = unknownArray;
console.log(a,b,c,d);
// Output: 1 5 9 undefined
对象解构
我们使用花括号:{}
来解构对象。我们必须提供与对象中的属性名称完全匹配的变量名称。(尽管我们还将看到一种如何使用不同变量名称的方法)。
让我们考虑与上面类似的restaurant
对象,还有更多的属性:
const restaurant = {
nameOfRestaurant: 'La\' Pinoz Pizza',
location: 'Ghaziabad',
categories: ['Italian', 'Vegetarian', 'Non-Vegetarian', 'Organic'],
starterMenu: ['Garlic Bread', 'Fries', 'Pastries'],
mainMenu: ['Pizza', 'Pasta', 'Risotto'],
order: function(starterIndex, mainIndex) {
return [this.starterMenu[starterIndex], this.mainMenu[mainIndex]];
},
openingHours: {
thu: {
open: 11,
close: 22
},
fri: {
open: 10,
close: 23
},
sat: {
open: 11,
close: 23
}
}
}
我们可以使用其属性名称来解构restaurant
对象,现在这里属性的顺序无关紧要,因为只要属性名称匹配就可以访问它。
const {nameOfRestaurant, openingHours, mainMenu} = restaurant;
console.log('Name: ', nameOfRestaurant);
console.log('Opening Hours: ', openingHours);
console.log('Main Menu: ', mainMenu);
// Output:
// Name: La' Pinoz Pizza
// Opening Hours: {
// thu: { open: 11, close: 22 },
// fri: { open: 10, close: 23 },
// sat: { open: 11, close: 23 }
// }
// Main Menu: [ 'Pizza', 'Pasta', 'Risotto' ]
使用不同的变量名
即使我们想更改与属性名称不同的变量名称,我们仍然需要提前知道属性名称。所以查找传入的对象总是一个好习惯。好的,所以我们可以使用冒号(:)
为属性名称指定别名。
const {nameOfRestaurant: name, openingHours: timing, mainMenu: menu} = restaurant;
console.log('Name: ', name);
console.log('Opening Hours: ', timing);
console.log('Main Menu: ', menu);
// We get the output similar to the above output.
设置默认值
我们总是可以在解构对象时为变量分配一个默认值。如果值存在于对象中,则将其分配给变量;如果不存在,则将默认值分配给变量。
const {nameOfRestaurant: name = 'PizzaHut', menu = [ ]} = restaurant;
// Lets assume that the restaurant object has no property with name 'nameOfRestaurant',
// In this case the name becomes 'PizzaHut'.
// On the other hand there is no menu property so menu is assigned with empty array.
变异值
在使用对象解构来改变值时,我们应该小心花括号,因为 javascript 会在遇到开放花括号时立即期望代码块。
为了解决这种情况,我们将解构代码包装在括号内。
let a = 11;
let b = 23;
let obj = { a: 120, b: 34 };
({ a, b } = obj); // Important line
console.log(a, b); // a = 120, b = 34