在 Javascript 中如何解构数组和对象

2021-09-17 17:01:19 浏览数 (4574)

在 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