Skip to content

解构数组、对象

解构数组

基本解构

js
const arr = [2, 3, 4];
const a = arr[0];
const b = arr[1];
const c = arr[2];

const [x, y, z] = arr;// 这里看起来像数组,但其实是解构任务

console.log(x, y, z); // 2 3 4

声明上面代码中的解构任务的时候,原数组不受影响。

跳跃解构

再看一个例子:

js
const restaurant = {
    name: 'Classico Italiano',
    location: 'Via Angelo Tavanti 23, Firenze, Italy',
    categories: ['Italian', 'Pizzeria', 'Vegetarian', 'Organic'],
    starterMenu: ['Focaccia', 'Bruschetta', 'Garlic Bread', 'Caprese Salad'],
    mainMenu: ['Pizza', 'Pasta', 'Risotto']
};

// 提取今日的主类别中的前两个
const [first, second] = restaurant.categories;

console.log(first, second);// Italian Pizzeria

如果想要提取第一个和第三个:

js
const [first, ,second] = restaurant.categories;

console.log(first, second); //Italian Pizzeria

通过解构来交换

当我们想要交换两个变量的时候,如果没有数组解构,我们需要创建一个临时变量作为中间变量,从而交换这两个变量。

但有了数组解构,我们可以这么做:

js
let [main, , secondary] = restaurant.categories;

[main, secondary] = [secondary, main]; // [] = array 的这种写法表示要对后面的数组进行解构并赋值给前面
console.log(main, secondary);// Vegetarian Italian

常用的还有解构函数的返回值,例如:

js
const restaurant = {
    name: 'Classico Italiano',
    location: 'Via Angelo Tavanti 23, Firenze, Italy',
    categories: ['Italian', 'Pizzeria', 'Vegetarian', 'Organic'],
    starterMenu: ['Focaccia', 'Bruschetta', 'Garlic Bread', 'Caprese Salad'],
    mainMenu: ['Pizza', 'Pasta', 'Risotto'],

    order: function(starterIndex, mainIndex){
        return [this.starterMenu[starterIndex], this.mainMenu[mainIndex]];
    }
};

const [starterFood, mainFood] = restaurant.order(2, 0);
console.log(starterFood,';', mainFood); // Garlic Bread ; Pizza

嵌套数组的解构

如果是一个嵌套数组,要如何解构呢?答案是相似的:

js
const nested = [2, 4, [5, 6]];
const [i, , [j, k]] = nested;
console.log(i, j, k);

给解构设置默认值

js
const [p = 1, q = 1, r = 1] = [8];
console.log(p, q, r); // 8 1 1

解构对象

基本结构

首先定义一个初始对象:

js
const restaurant = {
    name: 'Classico Italiano',
    location: 'Via Angelo Tavanti 23, Firenze, Italy',
    categories: ['Italian', 'Pizzeria', 'Vegetarian', 'Organic'],
    starterMenu: ['Focaccia', 'Bruschetta', 'Garlic Bread', 'Caprese Salad'],
    mainMenu: ['Pizza', 'Pasta', 'Risotto'],
    openingHours: {
        thu: {
            open: 12,
            close: 22,
        },
        fri: {
            open: 11,
            close: 23,
        },
        sat: {
            open: 0,
            close: 24,
        },
    },

    order: function (starterIndex, mainIndex) {
        return [this.starterMenu[starterIndex], this.mainMenu[mainIndex]];
    }
};

使用下方的语法进行对象解构:

js
const {name, openingHours, categories} = restaurant;

用上面这种方式进行对象解构的时候,需要保证左侧花括号内的变量名与对象内部想要得到的 key 相同。

如果我们想定义为不同的变量名呢?,可以如下所示:

js
const {name: restaurantName, openingHours: hours, categories: tags} = restaurant;

默认初始值

如果我们有希望他有一个默认的初始值,我们要怎么做?

js
const { menu = [], starterMenu: starters = [] } = restaurant;

即在进行声明的时候就进行赋值。

mutating variables

js
let a = 111;
let b = 999;
const obj = { a: 23, b: 7, c: 14 };

({a, b} = obj); // 加了括号,才能被理解为代码块,里面的事表达式,才能实施解构
console.log(a, b);

嵌套对象的解构

js
const {name: restaurantName, openingHours: hours, categories: tags} = restaurant;
const { fri: {open, close} } = hours;

console.log(open, close); // 11, 23

参数解构

首先在对象中加入一个方法 orderDelivery

js
const restaurant = {
    name: 'Classico Italiano',
    location: 'Via Angelo Tavanti 23, Firenze, Italy',
    categories: ['Italian', 'Pizzeria', 'Vegetarian', 'Organic'],
    starterMenu: ['Focaccia', 'Bruschetta', 'Garlic Bread', 'Caprese Salad'],
    mainMenu: ['Pizza', 'Pasta', 'Risotto'],
    openingHours: {
        thu: {
            open: 12,
            close: 22,
        },
        fri: {
            open: 11,
            close: 23,
        },
        sat: {
            open: 0,
            close: 24,
        },
    },

    order: function (starterIndex, mainIndex) {
        return [this.starterMenu[starterIndex], this.mainMenu[mainIndex]];
    },

    orderDelivery: function({mainIndex, time, address}){
        console.log(`now is ${time}`);
    }
};

然后调用这个方法:

js
restaurant.orderDelivery({
    time: '22.30',
    address: 'street N01',
    mainIndex: 2,
}); // now is 22.30

我们直接把一整个对象作为参数传入这个方法,方法直接对参数对象进行解构,这是一个非常方便的事情。

扩展运算符

js
const arr = [7, 8, 9];
console.log([5, 6, ...arr]); // [5, 6, 7, 8, 9]

扩展运算符的两种使用方式:

  1. 创建数组的浅拷贝 const newArray = [...arr];
  2. 拼接数组 [...arr, ...newArray]

扩展运算符以前只能应用于**可迭代对象**,这一特性从 ES2018 后被改变了,扩展运算符也可以用于对象了。

可迭代对象:数组、字符串、集合、映射。

注意💡:对象不是可迭代对象。

通过扩展运算符浅拷贝对象的方法如下:

js
const newRestaurant = {...restaurant};

Rest Pattern 剩余模式

js
// 展开模式,由于扩展运算符在等号右侧
const arr = [1, 2, ...[3, 4]];

// 剩余模式,由于扩展运算符在等号左侧
const [a, b, ...others] = [1, 2, 3, 4, 5];
console.log(a, b, others); // 1 2 [3, 4, 5]

剩余元素必须是最后一个元素。

同样的,剩余模式对对象也适用。

js
const {sat, ...weekdays} = restaurant.openingHours;