前言
随着 Web 技术的日新月异,JavaScript 也在不断地吸收新的特性和技术,以满足日益复杂和多样化的开发需求。在 2024 年,JavaScript 迎来了一系列令人瞩目的新功能,这些功能不仅提升了开发者的效率,也极大地丰富了 Web 应用的表现力和交互性。
在接下来的内容中,我们将逐一介绍这些新功能,并探讨它们如何在实际开发中发挥作用,以及它们如何继续引领前端开发的未来。
Object.groupBy
它是一个新的 JavaScript 方法,它可以根据提供的回调函数返回的字符串值对给定可迭代对象中的元素进行分组。返回的对象具有每个组的单独属性,其中包含组中的元素的数组。
当我们想要根据数组中对象的一个或多个属性的名称对数组元素进行分类时,此方法非常有用。
语法
Object.groupBy(items, callbackFn)
参数
items
:一个将进行元素分组的可迭代对象callbackFn
:对可迭代对象中的每个元素执行的函数。它应该返回一个值,可以被强制转换成属性键(字符串或 symbol),用于指示当前元素所属的分组。该函数被调用时将传入以下参数:- element:数组中当前正在处理的元素
- index:正在处理的元素在数组中的索引
返回值
一个带有所有分组属性的 null
原型对象,每个属性都分配了一个包含相关组元素的数组。
对数组中的元素进行分组
我们可能经常需要对数据库中的项目进行分组并通过 UI 将它们显示给用户。使用 Object.groupBy()
就可以简化此类项目的分组。
比如有这样一堆数据:
const arr = [
{ product: "iPhone X", quantity: 25, color: "black" },
{ product: "Huawei mate50", quantity: 6, color: "white" },
{ product: "xiaomi 13", quantity: 0, color: "black" },
{ product: "iPhone 13", quantity: 10, color: "white" },
{ product: "Huawei P50", quantity: 5, color: "black" },
]
然后我们希望将这些设备根据颜色进行分类
const newArr = Object.groupBy(arr, (item) => item.color)
console.log('【newArr】', newArr)
上面的代码按产品的属性值color
对产品进行分组,每次调用回调函数时,都会返回与每个对象的属性(“黑色”或“白色”)相对应的键。然后使用返回的键对数组的元素进行分组。
有条件地对数组中的元素进行分组
还是上面的数据,如果我们想要分成iphone和国产品牌两类,可以这么来实现:
const arr = [
{ product: "iPhone X", quantity: 25, color: "black" },
{ product: "Huawei mate50", quantity: 6, color: "white" },
{ product: "xiaomi 13", quantity: 0, color: "black" },
{ product: "iPhone 13", quantity: 10, color: "white" },
{ product: "Huawei P50", quantity: 5, color: "black" },
]
const list = Object.groupBy(arr, (item) => {
return item.product.includes('iPhone') ? 'iPhone' : '国产品牌'
})
console.log('【list】', list)
扩展
注意: Object.groupBy()
最初是作为典型的数组方法实现的。它最初的用途是这样的:
let myArray = [a, b, c]
myArray.groupBy(callbackFunction)
然而,由于ECMAScript技术委员会在实现该方法 时遇到了Web 兼容性问题,因此他们决定将其实现为静态方法 ( )。
Object.groupBy()
只需两个参数即可简化数组中对象分组的过程:数组本身和回调函数。
在过去,您必须编写一个自定义函数来对数组元素进行分组或从外部库导入分组方法。
可用性: Object.groupBy()
现在所有主要浏览器平台都支持
正则表达式v标志
大家可能熟悉正则表达式 Unicode 标志 ( u
),它允许启用对 Unicode 字符的支持。该v
标志是u
标志大部分功能的扩展。
它除了主要向后兼容该u
标志之外,还引入了以下新功能:
交集运算符
交集运算符可以匹配两个字符集中必须存在的字符。其语法为[operand-one&&operand-two]
,其中&&
表示交集运算符, operand-one
和operand-two
表示各自的字符集。
const str = 'My name is nanjiu'
const strReg = /[[a-z]&&[^aeiou]]/gv
const strArr = str.match(strReg)
console.log('【strArr】', strArr)
// 【strArr】 ['y', 'n', 'm', 's', 'n', 'n', 'j']
[a-z]
上面的代码定义了一个匹配小写字母和非元音字符的交集的正则表达式[^aeiuo]
。- 运算
&&
符确保仅匹配两个集合共有的字符。 - 这些
gv
标志启用全局搜索(查找所有匹配项)和正则表达式 v 模式。
差异运算符
差异运算符由两个连续的连字符 ( --
) 表示,提供了一种在正则表达式中指定排除项的便捷方法。正则表达式引擎将忽略--
后面的任何字符集
查找非 ASCII 表情符号字符:
let myEmojis = "😁,😍,😴,☉‿⊙,:O";
let myRegex = /[\p{Emoji}--\p{ASCII}]/gv;
console.log(myEmojis.match(myRegex));
// ["😁","😍","😴"]
可用性: 所有主要 JavaScript 环境都支持该v
标志。
Promise.withResolvers()
Promise.withResolvers()
是一个静态方法,它返回一个包含三个属性的对象:
- promise:一个新的peomise对象
- resolve:一个函数,用于解决该promise
- reject:一个函数,用于拒绝该promise
很多时候,我们希望能够在promise
外部访问resolve
和reject
,在这之前我们都是通过以下形式解决的
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
现在我们可以使用Promise.withResolvers
来优雅的解决这个问题,并且resolve
和reject
函数现在与 Promise 本身处于同一作用域,而不是在执行器中被创建和一次性使用。这可能使得一些更高级的用例成为可能,例如在重复事件中重用它们,特别是在处理流和队列时。这通常也意味着相比在执行器内包装大量逻辑,嵌套会更少。
const getList = () => {
const { resolve, reject, promise } = Promise.withResolvers()
setTimeout(() => {
const list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
resolve(list)
}, 1000)
return promise
}
getList().then(res => {
console.log('【res】', res)
})
// 【res】 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
可用性: 适用于所有主要浏览器。
注意:Promise.withResolvers()
尚未包含在 Node.js 中。因此,提供的示例可能无法在 Node.js 中按预期运行
四种新的非改变数组方法
通过复制改变数组引入了四种新的非改变数组方法: toReversed()
、toSpliced()
、toSorted()
和with()
前三个在功能上等同于它们的相似方法: reverse()
、splice()
和sort()
。
它们与对应方法的功能相似,区别在于新增的三个方法不会改变原数组
with()
是第四个新的数组方法。它允许我们替换数组中特定位置的元素,同样不会改变原数组
const groupList = [1, 2, 3, 4, 5, 6]
const newGroupList = groupList.with(2, 'nanjiu')
console.log('【newGroupList】', newGroupList)
console.log('【groupList】', groupList)
可用性: 适用于所有主要的 JavaScript 运行时和浏览器中。