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

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

上一篇:扎实个人技术,注重团队合作(构建之法读书笔记二)


下一篇:Exchange Server 2016 独立部署/共存部署 (七)—— DAG功能测试