你可能不知道 JavaScript 扩展运算符能做什么?
如果您觉得这篇文章有用,可以订阅我的邮件列表,查看我博客上的其他文章,或者在Twitter上关注我。我还有几个正在进行的业余项目,您可能想看看:
- ippy.io - 一款用于创建精美简历的应用程序
- many.tools - 为设计师和开发人员提供的实用工具集合
自从 ES6 引入扩展运算符以来,它就受到了 JavaScript 社区的热烈欢迎,这当然是有原因的!它极大地简化了许多常见的对象和数组操作模式。
虽然其常见用途受到广泛赞赏和利用,但它也促进了一些稍微不那么明显的模式。
例如…
👉 1)有条件地向对象添加属性
这也许并不常见,但想象一下(无论出于何种原因)你想要有条件地向一个对象添加属性。具体来说,你想要在属性值为真时添加它们,而在属性值为空、未定义或包含假值时排除它们。你会怎么做呢?
合理的方法可能是类似如下:
const firstName = 'Harrison'
const lastName = null
const address = '123 Street Rd'
const phoneNumber = null
const userInfo = {}
if (firstName) {
userInfo.firstName = firstName
}
if (lastName) {
userInfo.lastName = lastName
}
if (address) {
userInfo.address = address
}
if (phoneNumber) {
userInfo.phoneNumber = phoneNumber
}
console.log(userInfo)
// {
// firstName: 'Harrison',
// address: '123 Street Rd'
// }
这种方法没有什么问题 - 但是使用扩展运算符,我们可以将条件逻辑移动到对象文字内。
结果稍微简洁了一些,而且在我看来,一旦你看过几次之后,它实际上更具可读性。
看一下:
const firstName = 'Harrison'
const lastName = null
const address = '123 Street Rd'
const phoneNumber = null
const userInfo = {
...firstName && { firstName },
...lastName && { lastName },
...address && { address },
...phoneNumber && { phoneNumber }
}
console.log(userInfo)
// {
// firstName: 'Harrison',
// address: '123 Street Rd'
// }
如果你之前没见过这种模式,可能需要花点时间才能理解。我会尝试解释一下:
让我们考虑对象文字中的第一行,其中应该将属性添加到对象的情况:
...firstName && { firstName }
由于firstName
先前已赋值为真值'Harrison'
,
表达式firstName && { firstName }
将返回{ firstName: 'Harrison' }
。 的左侧和右侧均被&&
评估为真值,因此返回右侧。
然后将此返回的对象传播到userInfo
对象中,从而成功设置 firstName 属性。
接下来,我们考虑另一种情况,即尝试赋一个 false 值。我们来看对象字面量的第二行:
...lastName && { lastName }
在这种情况下,lastName
为空。这意味着表达式lastName && { lastName }
短路返回 的左侧&&
,在本例中为null
。
然后我们尝试将其扩散到对象null
中userInfo
。你可能认为这会导致错误,但实际上不会。
事实上,据我所知,将任何 false 值传入对象都是完全有效的语法,但不会导致对象发生任何变化。试试看:
let obj = { ...null }
console.log(obj)
// {}
let obj = { ...undefined }
console.log(obj)
// {}
let obj = { ...false }
console.log(obj)
// {}
let obj = { ...'' }
console.log(obj)
// {}
let obj = { ...0 }
console.log(obj)
// {}
let obj = { ...{} }
console.log(obj)
// {}
let obj = { ...[] }
console.log(obj)
// {}
所有这些的最终结果是,任何真值都将被添加到对象中,而任何假值都将被忽略!
为了使代码更加明确,我们可以使用相同的模式,但将真实性检查重构为其自己的函数:
const hasIfTruthy = (propertyName, property) => {
return property && { [propertyName]: property }
}
const firstName = 'Harrison'
const lastName = null
const address = '123 Street Rd'
const phoneNumber = null
const userInfo = {
...hasIfTruthy('firstName', firstName),
...hasIfTruthy('lastName', lastName),
...hasIfTruthy('address', address),
...hasIfTruthy('phoneNumber', phoneNumber)
}
console.log(userInfo)
// {
// firstName: 'Harrison',
// address: '123 Street Rd'
// }
使用这种模式,您甚至可以完全改变决定某个属性是否被包含或排除的条件 - 它不一定需要仅基于真实性/虚假性。
👉 2)将数组展开为对象
所以...我还没有想到一个特别令人信服的理由让你真正这样做(如果有的话请在评论中大声说出来),但你完全可以将一个数组展开到一个对象中。
结果是将每个数组元素插入到对象中,并将键设置为其各自的数组索引。
一探究竟:
const fruitsArray = ['apple', 'orange', 'banano']
const fruitsObject = { ...fruitsArray }
console.log(fruitsObject)
// {
// 0: 'apple',
// 1: 'orange',
// 2: 'banano'
// }
👉 3)将字符串扩展为数组(或对象)
这个其实挺巧妙的,而且可能比其他的更广为人知。你可以把一个字符串展开成一个数组!
结果是一个包含字符串中各个字符的数组。
在我看来,这比常见的风格允许更令人愉快的语法'string'.split('')
。
这里是:
const characters = [..."apple"]
console.log(characters)
// ['a', 'p', 'p', 'l', 'e']
如果你真的想尝试一下,你甚至可以将字符串展开到一个对象中🙀
const characters = {..."apple"}
console.log(characters)
// {
// 0: 'a',
// 1: 'p',
// 2: 'p',
// 3: 'l',
// 4: 'e'
// }
孩子们,在外面一定要注意安全。
你知道 JS 扩展运算符还有什么奇特或奇妙的用法吗?欢迎在评论区留言告诉我😊
文章来源:https://dev.to/harrison_codes/3-weird-things-you-probously-didn-t-know-you-can-do-with-the-javascript-spread-operator-2fln