如果想从 'uid: 123'
字符串中匹配出 123 我通常会 'uid: 123'.match(/uid: (\d+)/)[1]
。
但如果字符串不符合规范,正则会返回 null 导致 [1] 操作报错 Uncaught TypeError: Cannot read property '1' of null
。
所以我会 ('uid: null'.match(/uid: (\d+)/) || 0)[1]
来防止报错。
但这样很不优雅。
Symbol.match
先看看官网文档 Symbol.match。
写的相当简陋,甚至只说了他设为 false 时,正则将视为普通字符串,就没再说啥了。
在文章末尾的浏览器兼容性中可以看到,除了IE全兼容。
优化 match 返回值
1 | const re = { |
其实不难发现,通过 Symbol.match 劫持字符串的 match 操作,字符串的 match 操作可以自定义。
这里的 re 是死的,不方便复用,所以我们优化下代码。
1 | const r = (re) => { |
只是在原先的正则上加个 r 函数。
看起来不是那么好看,我们继续优化一下。
1 | const r = (re) => ({ [Symbol.match]: (str) => str.match(new RegExp(re)) || [] }); |
这里借助 模板字符串(template literals) + 标签模板(tagged template) 优化了正则体验。
小结
这里只例举了一个小小的应用场景,作为抛砖引玉,Symbol的其他属性,也有各种不同的妙用,自己去挖掘吧。