2021 JavaScript最全解构用法总结

485 阅读6分钟

引言

记录真的是一件一劳永逸的事情 作为掘金的第一篇blog, 希望大家多多支持!

2021的flag:每月最少更新两次!

今日分享

最近看到一个喜欢的Youtuber的一句话分享给大家:

You can't go back and change the beginning, but you can start where you are and change the ending

进入正题!

JavaScript中最常用的两种数据结构是对象和数组。ECMAScript 2015引入的解构赋值是一种简化语法,允许我们将数组值或对象属性提取到变量中。这篇文章我将详细介绍这两种数据结构的语法,并给出使用它们在工业界中常见的的应用示例。

1. 为什么需要解构(destructing)

解构无疑在我们写javascript中用到不能再多,它可以很方便的帮助我们从一个复杂的对象或者数组中提取出有用的部分,例如React中的props。学会去如何正确并且写出非常简洁的解构代码可以说非常关键了!

我们可以提取多个属性用一行代码,甚至可以自己接获取子对象(nest object),以及设置一些初始化的值。这对某些不确定是否存在的属性来说至关重要

img

2. 解构对象

让我们从最简单的提取一个属性(property)入手

const props = {
    name: "xxx",
    address: "xxx",
    phone: 123
}
const {name} = props;

假设props这个object有很多个属性,例如name, address, phone等等,但是我们只需要其中的name属性,这行代码可以帮我们快速的拿到,另一种写法是

const name = props.name;

在业界中,大家普遍使用第一种更加clean的方法,我在这里也建议大家使用第一种。‌

提取多个属性跟上面十分类似,我们枚举出所需要的属性,不同属性之间用 , 分开即可。这种one line的写法就会比拆分各个属性的写法简洁很多,code review中如果你使用第二种写法,基本也是不会让你过的。

// method 1 (prefer)
const {name, address, phone} = props;


// method 2
const name = props.name;
const address = props.address;
const phone = props.phone;‌

很多小伙伴就会问了,如果解构出来的属性在对象中没有怎么办?会报错么?如果没有的话如何加上初始值呢? 下面正要讲这些关键的点!

key 1: 解构一个没有的属性会直接返回undefined并非报错

const {age} = props;


console.log(age); // => undefined

返回一个undefined的好处我觉得给我们开发人员更多的自由性。当访问到了不存在的属性时,有些时候我们不希望我们的程序直接crash掉,因为有些场景我们不知道object是如何定义的,有些场景我们的object会随着业务的升级而改变具体的属性,返回undefined可以很好的帮助我们兼容这些特殊的场景,使我们的代码正常的运行。

key 2: 增加初始化值

这种可能undefined的属性我们常常会搭配着default value进行使用。这里0代表如果props里面没有age这个属性的话,我们初始化age = 0。

const {age = 0} = props;

这其实相当于下面这种 更容易理解的写法,但是clean程度大不如上面这种。

const age = props.age === undefined ? 0 : props.age;

key 3: 使用aliases 替换原object中的命名

我们可能会有顾虑,如果我们不想用默认的名称怎么办?很简单,我们只需要在: 后面加上新名称即可

const {name : newName} = props;

如果想即给新的变量命名并且提供默认值的话也非常简单

const {name:newName = "empty"} = props;

了解完这些简单的之后,让我们看看稍微复杂的解构是如何操作的

const props = {
    name: {
        firstName: "Chris",
        lastName: "Paul"
    }
    address: "xxx",
    phone: 123
}


const {name: {lastName}} = props;
console.log(lastName) // Paul
console.log(name) // undefined

这其实相当于

const name = props.name.lastName;

嵌套的层数没有上限,我们更通用的写法可以像下面这样

const { propA: { propB: { propC: { .... } } } } = object;

有一个关键的地方需要注意,如果我们尝试去解构lastName, 那么我们如果去访问name的话会得到undefined。这一点非常关键,当我们尝试去访问子属性的时候,它本身绑定的父属性并不会被创建,这个一定要注意。

在农业生产中我们写代码往往即要提取一些属性,也要保留剩下的属性。这时候我们可以使用...创建一个具有所有未被解构的属性的对象。例如:

let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
a; // 10
b; // 20
rest; // { c: 30, d: 40 }

3. 解构数组

当需要解构数组时,需要使用[]而不是{}。最简单的例子如下:

const arr = [1, 2, 3]
const [a, b] = arr
console.log(a)
console.log(b)


------------------------
Output
------------------------
1
2

除此之外,我们可以用不同的变量映射数组的每个位置。下面总结了一些很常用的技巧。

1)跳过元素

我们使用 , 可以帮助我们按顺序跳过元素,例如:

const arr = [1, 2, 3]
const[a,,b] = arr
console.log(a)
console.log(b)


------------------------
Output
------------------------
1
3


const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const [a,, b, ...z] = arr
console.log(a)
console.log(b)
console.log(z)
------------------------
Output
------------------------
1
3
[4, 5, 6, 7, 8, 9, 10]

如果将数组当作对象来解构,则可以使用索引作为属性,从而访问数组中的任何位置(注意index是从0开始)。例如:

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const { 2: two, 4: fourth } = arr
console.log(two)
console.log(fourth)
------------------------
Output
------------------------
3
5

2) 数组默认值

在解构数组时,还可以为未定义的属性设置默认值。但是,当我们使用扩展运算符...时,我们不可以设置默认值,在undefinedd的情况下,它将返回一个空数组。

const [missing = 'default missing'] = []
const [a, b, c = "missing c", ...others] = [1, 2]
console.log(missing)
console.log(a)
console.log(b)
console.log(c)
console.log(others)
------------------------
Output
------------------------
default missing
1
2
missing c
[]

3) 交换变量

这里的用法跟python很像,我们可以用一行代码来实现元素的交换

let a = 1
let b = 2
[a, b] = [b, a]
console.log(a)
console.log(b)
------------------------
Output
------------------------
2
1

4)动态变量

有些时候,我们使用的key不是静态的string, 而是动态保存在某些变量里的。这时候我们同样可以灵活的使用解构, 只需要把变量放到[]里面即可,例如:

const props = { name: "XXX" }
let dynamicVar = 'name'
let { [dynamicVar]: myName } = props
console.log(myName)
------------------------
Output
------------------------
XXX

另一个常见的用法是:我们经常会在function的参数中直接进行解构,例如:

function foo({name}) {
    console.log(name);
}


---------
equal to
---------


function foo(props) {
    const {name} = props;
    console.log(name);
}

总结‌

对象解构是一个强大的特性,它允许我们从对象中提取属性并将这些值绑定到变量。‌

我特别喜欢的是对象解构的简洁语法和在一条语句中提取多个变量的写法。很多新手在刚使用解构的时候难免会有一些笨拙的用法,一旦我们掌握了这些简单实用的例子之后可以帮助你写出简洁,可读性更强的代码。

希望这边总结可以帮助你熟悉解构的用法,以及如何写出漂亮实用的代码!

参考文献:

Destructuring assignment - JavaScript

Write Cleaner Code by Using JavaScript Destructuring