每年都发布几个新功能,来看看目前确定的2025发布的功能有哪些
同名具名捕获组
曾几何时正则表达式中的捕获组是不支持命名的,只能按顺序获取。
1 | const matched = '2012-12'.match(/(\d{4})-(\d{2})/) |
匹配结果matched是一个数组,数组第一项是正则匹配的完整的字符串,从第二项开始就依次是捕获组的内容,所有year和month分别是数组第二项,和第三项。
可以命名的捕获组
还是上面的例子
1 | const matched = '2012-12'.match(/(?<year>\d{4})-(?<month>\d{2})/) |
可以看到把匹配结果中增加了一个groups属性。并且使用了我们的捕获给名称作为键值。这就非常方便了,后续解构时也很方便,并不用区分对应的捕获组在正则中的位置,一旦正则调整,只要捕获组名称没有动,后面的解析就不需要更改。否则很可能出现动了正则,变更了捕获组顺序而不自知的事情。
既然捕获组在groups对象中是以其名称来作为键值的,那这就要求捕获组之间不能重名,否则在groups对象中要出现同名覆盖,丢失捕获组的情况了。
1 | '5987'.match(/([a-z]{4})|([5-9]{4})/); |
第一个捕获没有匹配上,第二个捕获组匹配上了。如果这两个捕获组对我而言意义相同,这个时候是不能使用具名捕获组的,会报错
1 | '5987'.match(/(?<code>[a-z]{4})|(?<code>[5-9]{4})/); |
当然上面这个问题你可以通过调整正则,在捕获组内使用|
来区分不同的匹配方式
同名捕获组
新功能就是解决这个问题的,只要能保证捕获组不会同时匹配到内容,就是可以使用相同的名称,那如何保证呢,自然是像上面那样使用|
把捕获组放在不同的分支下。看一下提案中使用的正则
1 | /(?<year>[0-9]{4})-[0-9]{2}|[0-9]{2}-(?<year>[0-9]{4})/ |
这个正则支持两种年月匹配模式2024-10或者10-2024 。使用 |
把两种模式区分开,确保不会同时被匹配上,也就杜绝了groups对象中同名覆盖的问题。
1 | const matched = '2024-10'.match(/(?<year>[0-9]{4})-[0-9]{2}|[0-9]{2}-(?<year>[0-9]{4})/); |
不管是哪种形式的年月字符串,只要能被匹配上,都可以直接从groups对象中获取year
集合的新方法
intersection(other)
求交集,返回一个新集合,新集合的元素既在this集合中,也在other集合中
union(other)
求并集,返回一个新集合,新集合元素包含this和other中所有的元素
difference(other)
求差集,返回一个新集合,新集合元素在this集合中,但不在other集合中
symmetricDifference(other)
求对称差,返回一个新集合,新集合元素只在this集合中或只在other集合
isSubsetOf(other)
this集合是否为other集合的子集
isSupersetOf(other)
this集合是否为other集合的父集
isDisjointFrom(other)
this集合和other集合是否没有共同元素,也就是交集是否为空
有了这些方法,将大大简化我们的一些业务处理逻辑
正则修饰符
这次不是新增修饰符,而是修饰符功能增强
1 | /javascript/.test('Javascript') // false |
如果希望能够匹配上,也就是忽略大小写
1 | /javascript/i.test('Javascript') // true |
这样添加忽略大小写的修饰符就可以实现需求。但同时对于后面的字符也都忽略了大小写。如果我的需求是只有首字符忽略大小写。其它的仍然要保持大小写敏感状态,在以前单纯通过修饰符是不可能实现的。因为修饰符是针对整体正则表达式的,无法针对其中一部分。不过现在可以了
1 | /(?i:j)avascript/.test('Javascript') // true |
(?:)是非捕获分组,本次新功能就是在分组内调整修饰符。正则表达式整体是大小写敏感的,但是在分组内使用大小写不敏感模式。
本次新功能支持在分组中添加修饰符或者移除修饰符 (?imsx-imsx:subexpression)
可以看到支持 imsx 四种修饰符,使用**-**来标记是移除一个修饰符
x 修饰符是不是看着有点陌生。对的,它还没成功标准,还在提案阶段
Import Attributes
在原生不借助打包工具的情况下,是无法通过import语句导入一个json文件的。这个新功能就是解决这样一个问题的。
1 | import json from './test.json' with {type: 'json'}; |
通过在导入语句后面添加 with 来标注更多信息,这里则是通过type来注明导入的是一个json文件。这样才可以正常的输出json内容。
当然也支持异步导入
1 | import('./test.json', { with: { type: 'json' } }).then(m => console.log(m.default)); |
这就厉害了,后续会不会支持各种其它的类型,然后都不需要打包工具了
JSON modules
其实就是上面导入的json模块,后续也许还会有其它模块支持
Iterator Helpers
这是给迭代器增加了一些方法,方便在处理迭代器的时候更加方便
1 | function* gen() { |
这个itr只可以调用生成器的next, return, throw方法,迭代器上没什么可用方法,现在不一样了,迭代器上加了各种方法drop
, every
,filter
, find
, flatMap
, forEach
, map
, reduce
, some
, take
, toArray
, Iterator.from
其中Iterator.from
是静态方法
上面的各种方法除了drop和take都跟数组很像,使用也很像。
而 take是只取前n个结果 ,drop是丢弃前n个结果
Promise.try
这是给 Promise 又添加了一个新的静态方法, 其语法如下
Promise.try ( callbackfn, …args )
第一个参数是要立即执行的函数,后面的参数是需要传给这个函数的,函数执行成功, try 得到的promise将会进行fulfilled状态,如果函数异步,try得到的promise进行rejected状态