ECMAScript 双月报告:TC39 2022年1月会议提案进度汇总

简介: 本次 TC39 会议中仅有 reversible-string-split 提案获得了阶段性进展,由 Stage 0 进入到 Stage 1,其他较受关注的提案如 array-from-async、原生枚举类型,以及在上一次会议中进入到 Stage 1 的 Intl.Segmenter v2 ,在本次会议中都没有取得阶段性进展。

Stage 0 → Stage 1



从 Stage 0 进入到 Stage 1 有以下门槛:

  1. 找到一个 TC39 成员作为 champion 负责这个提案的演进;
  2. 明确提案需要解决的问题与需求和大致的解决方案;
  3. 有问题、解决方案的例子;
  4. 对 API 形式、关键算法、语义、实现风险等有讨论、分析。
    Stage 1 的提案会有可预见的比较大的改动,以下列出的例子并不代表提案最终会是例子中的语法、语义。


Reversible String Split

提案链接:https://github.com/tc39/proposal-reversible-string-split


JavaScript中的 split 方法能够基于指定的分隔符来拆分一个字符串,并将每次拆分的子项保存在一个数组中返回,它接收两个参数:

  • separator,即用于拆分的分隔符,可以是字符串或正则表达式。
  • limit,返回的拆分结果数组的长度,或者也可以理解为进行拆分的次数。

需要注意的是,当你指定了 limit 参数,split 方法的返回值并不会包含由于达到上限而停止拆分的剩余部分,如上面的例子中,剩余的字符串被直接抛弃了:

const str = 'a|b|c|d|e';
// ["a", "b"], 字符串的剩余部分被抛弃了
console.log(str.split("|",2))

这即是此提案所关注的核心问题,因为在其他主流语言中,字符串的 split 方法都将在达到拆分上限时返回余下的部分,如:


Java 代码:

class Playground {
  public static void main(String[] args) {
    String s = new String("a|b|c|d|e|f");
    for(String val : s.split("\\|", 2)) {
      System.out.println(val);
    }
  }
}
// a
// b|c|d|e|f


Rust 代码:

fn main() {
  let v = "a|b|c|d|e|f".splitn(2, "|").collect::<Vec<_>>();
  println!("{:?}", v);
}
// ["a", "b|c|d|e|f"]


Go 代码:

package main
import (
  "fmt"
  "strings"
)
func main() {
  fmt.Printf("%#v", strings.SplitN("a|b|c|d|e|f", "|", 2))
}
// []string{"a", "b|c|d|e|f"}


以及 Python 代码:

print('a|b|c|d|e|f'.split('|', 2))
# ['a', 'b', 'c|d|e|f']

可以看到,Java、Rust、Go、Python 中的 split 方法都会在拆分次数达到 limit 后,返回余下的部分。虽然这里 Python 与其他语言也存在着不同,它会进行 N 次拆分,返回一个 N + 1 长度的数组,而其他语言认为 N 直接代表着返回值数组的长度,因此进行 N - 1 次拆分,返回一个 N 长度的数组。


这些语言和 JavaScript 的 split 方法有一个很明显的区别,即它们的 split 方法返回值由于包含了剩余部分,所以能再次通过 join 方法拼接得到原本的字符串(即 reversible),而 JavaScript 则做不到。这一反转过程可以用以下的伪代码表示:

join(Separator, Value.split(Separator, Limit)) == Value;


为了解决这一问题,同时不影响现有的 split 方法的表现,此提案提出新增一个 splitN 方法,其表现与 Java、Go 语言一致,进行 N - 1次拆分,返回一个长度为 N 的数组,包含字符串的余下部分。

console.log("a|b|c|d|e|f".splitN("|", 2));
// ["a", "b|c|d|e|f"]


而关于为何 JavaScript 的 split 方法会有着如此的表现,作者也在最后提到原因已经无可追溯,能查证的资料表明 split 方法的第二个参数最初是在 1997 年的 Netscape Navigator 4 浏览器中首次支持,而在 ECMA262 中首次明确的记录版本是在 ES3。


结语


由贺师俊牵头,阿里巴巴前端标准化小组等多方参与组建的 JavaScript 中文兴趣小组(JSCIG,JavaScript Chinese Interest Group)在 GitHub 上开放讨论各种 ECMAScript 的问题,非常欢迎有兴趣的同学参与讨论:https://github.com/JSCIG/es-discuss/discussions

相关文章
|
消息中间件 数据可视化 Java
Linxu下RocketMq及可视化界面的搭建
Linxu下RocketMq配置信息及可视化界面的搭建
1462 0
|
机器学习/深度学习 人工智能 自然语言处理
【Python机器学习】文本特征提取及文本向量化讲解和实战(图文解释 附源码)
【Python机器学习】文本特征提取及文本向量化讲解和实战(图文解释 附源码)
782 0
|
10月前
|
监控 Cloud Native BI
8+ 典型分析场景,25+ 标杆案例,Apache Doris 和 SelectDB 精选案例集(2024版)电子版上线
飞轮科技正式推出 Apache Doris 和 SelectDB 精选案例集 ——《走向现代化的数据仓库(2024 版)》,汇聚了来自各行各业的成功案例与实践经验。该书以行业为划分标准,辅以使用场景标签,旨在为读者提供一个高度整合、全面涵盖、分类清晰且易于查阅的学习资源库。
359 8
|
存储 Cloud Native 数据挖掘
Ganos
Ganos
334 3
|
Java API Spring
Spring6(七):手写IoC
Spring6(七):手写IoC
131 0
|
小程序
微信小程序实现“转发给朋友”、“分享到朋友圈”
微信小程序实现“转发给朋友”、“分享到朋友圈”
|
Java 关系型数据库 数据库连接
连接池的工作原理
连接池的工作原理
|
开发框架 安全 搜索推荐
如何使用Python Flask发布web页面至公网并实现远程访问【内网穿透】
如何使用Python Flask发布web页面至公网并实现远程访问【内网穿透】
|
安全 Go 调度
Go协程探秘:轻量、并发与性能的完美结合
Go协程探秘:轻量、并发与性能的完美结合
459 0
|
存储 Ubuntu Docker
docker环境安装
docker环境安装
286 0