译者注:
这篇文章想表达的意思是我们尽量使用解构来获取对象的属性
且在解构时应该设置默认值防止解构的属性不存在
例如解构
objcet
对象的属性a
,const {a = 'hello'} = object
如果你不是到处都在解构,那你就做错了。
这或许是一些大胆的陈述,但请先听我解释......
首先,在许多地方使用点运算符(.
)都是非常完美的。知道哪里使用、为何使用点运算符,才是这篇文章所要讨论的地方。但是关于解构以及许多开发人员关于解构所不知的东西这方面的内容要重要得多。
其次,让我们从头开始认识一下 ES2019 向 JavaScript 引入了两个新的运算符:
- 可选链:
?.
- 空合并值:
??
这就意味着我们可以写 user?.name ?? 'Noname'
并且不用关心 user
是否存在,如果user
或name
中的任何一个不存在,则有一个fallback。
这些都很不错,但是没有解构好
为什么呢....
让我们从头开始思考
Photo by Mikaela Stenström on Unsplash
也许您正在玩一些家庭自动化脚本,并且您为某些数据结构键入了一个辅助函数,如下所示。您知道 celsius
并不总是存在,因此您可以设置默认值,当celsius
不存在时返回该默认值。
译者注:如果
atticData.celcius
没有值,则就有一个默认值返回,在这里为 15
const getTemperature = (atticData) => atticData.celcius || 15;
这个函数会有两个严重的问题:
- 如果你给函数的对象在某个时候未初始化,或者为
undefined
时?这个函数运行时会报错 - 如果
atticData.celcius
为0
,这个函数则会返回15
(行为不符合我们的预期)
使用开头提到的两个新运算符,您可以修复该函数:
const getTemperature = (atticData) => atticData?.celcius ?? 15;
两个问题都解决了。这很棒。
难道我们应该在所有地方都使用
?
运算符 ?
并不是,由以下两个理由:
- 它只会妨碍任何已知静态结构的可读性,API,例如
JSON.parse
、window.localStorage.getItem
或者其他已经导入库的标识符 - 在我们处理任何数据的大多数其他情况下,解构可能是更好的选择。
继续我们上面的示例函数 - 它会用解构编写,如下所示:
const getTemperature = ({ celcius = 15 } = {}) => celcius;
它稍微干净一点,实际上它变得更通用,因为它不一定对它的操作判断。我们避免命名。任何潜在的对象都可以被赋予这个函数,它会尝试安全地提取一个摄氏度。
另一种思考方式是,在我们的函数中,我们永远不需要引用数据对象,只需要引用它里面的东西。所以我们尽可能早地挖掘出来。
尽早解构
记住正确的工具
每当你使用点(
.
)取获取对象的属性时,停下来想想你是否已经解构了你所追求的值。
它通常使代码更短,控制更高。主要是因为可以设置默认值,也因为有可能在多层次解构,“深度解构”,然后一路设置安全的默认值。
如前所述 - 已知静态 API 不需要解构。但是,任何数据,甚至一些您认为是静态的配置,都值得使用默认值进行解构。
使用解构
让我们看看我们可以用解构做什么:
上面的例子是一个高阶函数/thunk/curried function/factory(亲爱的孩子有很多名字),它以不同的方式利用了解构特征。让我们进行分析:
- 在两个函数头中的第一/最高级别设置默认值可确保我们不会因 func()() (空参数)而崩溃。
- 使用值 (msg) 时,重命名长键名称以获得更易读的逻辑。
- 如果您只需要成员值中的内容,请使用深度解构。但同样,请记住还要添加一个默认值,以便在成员值不存在的情况下使解构安全免于崩溃。
- 还可以使用 rest 运算符来处理所有未显式解构的内容,这非常强大。
- 如果我们都需要使用整个结构体和内部的值,我们在函数作用域中解构(否则在函数头中,尽可能早地)。
- 解构和 rest 运算符也可用于数组。
- 如果一个值在范围内多次使用,我们不必为它重复一个长表达式
options.pos.x
。相反,只是 x。更干净、更安全、更高效,因为 JS 不必每次都挖掘价值。
结论
你应该从这篇文章知道以下内容:
- 一旦你使用点运算符(
.
) - 停下来想想这是否是您正在操作的数据。如果是这样 - 请改用解构。 - 尽早解构。
- 请记住设置默认值,尤其是在深度解构时。
译者注: