Any application that can be written in JavaScript, will eventually be written in JavaScript. ------Jeff Atwood
1 什么是TC39?
首先说下Javascript和ECMAScript的区别:
Javascript: the programming language that is implemented by various platforms (browsers, Node.js, Deno, etc.)
ECMAScript is designed by the Technical Committee 39 (TC39) of the standards organization Ecma International.
ECMAScrip名称中的‘ECMA’部分来源于Ecma组织,这是一个总部设在瑞士的标准化组织。
ECMA最初是“欧洲计算机制造商协会”的首字母缩写,其最初的名称后来演变为Ecma国际(Ecma)。
Ecma开发了许多与计算机产业有关的标准,制定标准的实际工作由Ecma技术委员会负责,该委员会简称‘TC’。当一个新的Ecma TC被创建的时会被分配一个序列号作为唯一标识,TC39是为了标准化Javascript而创建的TC。
Ecma会为其TC撰写的每份不同的标准各分配一个编号,并添加ECMA-前缀。ECMAScript标准被指定为ECMA-262。
TC39 成员来自于Adobe, Apple, Facebook, Google, Microsoft, Mozilla, Opera, Twitter等公司
Every two months, TC39 has meetings that member-appointed delegates and invited experts attend. The minutes of those meetings are public in a GitHub repository.
2 TC39提案流程
image.pngNew ECMAScript features must be proposed to TC39.
-
ECMAScript 各项特性独立设计,历经 5 个阶段,从 Stage 0(Strawman,初稿)开始,经 Stage 1(提案)、Stage 2(草案)、Stage 3(候选提案),最后到 Stage 4(Finished,过审提案)结束
-
Stage 1阶段需要明确解决的问题和大致的解决方案,Stage 2使用正式的语言详细地描述语法、语义,运行时行为变更,Stage 3阶段在各种javascript引擎中实现并根据实现反馈微调,Stage 4定案阶段准备在接下来的ECMAScript年度版本中发布
-
要求在后几个阶段进行原型实现和实际测试(由Test 262负责),以便在设计和实现之间形成反馈循环
-
ECMAScript 每年发布一版,囊括截止最后发版日期之前所有已经进入第 4 阶段的特性
-
如果你对某个提案有需求、意见,或者对于语言特性有新的需求,可以在提案的Stage0、1、2阶段参与进来。有很多方式可以参与:直接加入GitHub Issues讨论、更新spec text等等。对于一些新的想法,也可以通过下面的网址找找有没有在TC39中讨论过。
GitHub上: https://github.com/tc39/proposals
会议记录: https://github.com/tc39/notes
讨论组: https://es.discourse.group
2.1 stage 4
在第 4 阶段,一个规范已经完成,并被确定会包含到 ECMAScript 规范草案中。除非在特殊情况下,否则该提案是完整的、稳定的,并可随时发布。通常各个实现默认开启第 4 阶段的特性,没有任何特殊的标志。不去实现和交付第 4 阶段的特性,就有可能使该实现与其他实现不同步。
2.2 stage 3
在第 3 阶段,委员会正在全力考察一项功能,并已就具体细节达成一致。但实施过程仍然可能导致语义上的变化,甚至一些第 3 阶段的功能已经被完全放弃。追求稳定性的项目如果想完全交付这些功能,在交付第 3 阶段的功能之前,通常会使用一定程度的个例测试。
2.2.1 JSON Modules
import json from "./foo.json" assert { type: "json" };
import("foo.json", { assert: { type: "json" } });
2.2.2 Temporal
Date has been a long-standing pain point in ECMAScript. This proposes Temporal, a global Object that acts as a top-level namespace (like Math), that brings a modern date/time API to the ECMAScript languag.
原事件方案缺点:
- 不支持除用户本地时间以外的时区,不支持开发人员通过API来切换时区信息
- 计算API缺失,如比较两个时间的长短,时间之间的加减运算
- 不支持非公历,各国无法使用自己的历法,如中国的农历
2.2.3 Import Assertions
The Import Assertions proposal adds an inline syntax for module import statements to pass on more information alongside the module specifier. The initial application for such assertions will be to support additional types of modules in a common way across JavaScript environments, starting with JSON modules.
2.3 stage 2 、stage1、stage0
在第 0、1 和 2 阶段,语义细节尚无定论。委员会还没有就该提案的所有具体细节达成共识。在这个阶段的实现应该被认为是实验性和推测性的。这个阶段的实现对于程序员的实验是非常有价值的,它可以帮助完善语言的设计。实现往往通过特殊的标志来暴露这个阶段的特征,这些标志在默认情况下是不启用的。
2.3.1 Pipe Operator (|>) for JavaScript
image.png- %代表上一次操作的返回值
- |> 右侧可以是任何合法的表达式
3 ES2022
3.1 .at()
const cart = ['🍎', '🍌', '🍍'];
// first element
cart.at(0); // '🍎'
// last element
cart.at(-1); // '🍍'
// out of bounds
cart.at(-100); // undefined
cart.at(100); // undefined
3.2 Top level await
const i18n = await import(`./content-${language}.mjs`);
// 依赖倒退
let jQuery;
try {
jQuery = await import('https://cdn-a.com/jQuery');
} catch {
jQuery = await import('https://cdn-b.com/jQuery');
}
3.3 Error cause
try {
maybeWorks();
} catch (err) {
throw new Error('maybeWorks failed!', { cause: err });
}
3.4 Object.hasOwn
let books = {}
books.prop = 'exists';
// `hasOwn` will only return true for direct properties:
Object.hasOwn(books, 'prop'); // returns true
Object.hasOwn(books, 'toString'); // returns false
Object.hasOwn(books, 'hasOwnProperty'); // returns false
// The `in` operator will return true for direct or inherited properties:
'prop' in books; // returns true
'toString' in books; // returns true
'hasOwnProperty' in books; // returns true
与hasOwnProperty区别:
const obj = Object.create({});
obj.name = "xl";
console.log(obj.hasOwnProperty("name")); // true
const obj1 = Object.create(null);
obj1.name = "xl";
try {
console.log(obj1.hasOwnProperty("name"));
} catch (error) {
console.log(error); // error: obj1.hasOwnProperty is not a function
}
const obj2 = Object.create(null);
obj2.name = "xl";
console.log(Object.hasOwn(obj2, "name")); // true
3.5 RegExp match indices
However, there are several more advanced scenarios where this information may not necessarily be sufficient. For example, an ECMAScript implementation of TextMate Language syntax highlighting needs more than just the
index
of the match, but also the start and end indices for individual capture groups.
// 至少一个 a 以及 0 个或者 1 个 z ,其中包含一个命名为 Z 的捕获组
const re1 = /a+(?<Z>z)?/d;
// indices are relative to start of the input string:
const s1 = "xaaaz";
const m1 = re1.exec(s1);
m1.indices[0][0] === 1;
m1.indices[0][1] === 5;
s1.slice(...m1.indices[0]) === "aaaz";
m1.indices[1][0] === 4;
m1.indices[1][1] === 5;
s1.slice(...m1.indices[1]) === "z";
m1.indices.groups["Z"][0] === 4;
m1.indices.groups["Z"][1] === 5;
s1.slice(...m1.indices.groups["Z"]) === "z";
// capture groups that are not matched return `undefined`:
const m2 = re1.exec("xaaay");
m2.indices[1] === undefined;
m2.indices.groups["Z"] === undefined;
// e.g
const matchObj = /(a+)(b+)/g.exec('aaaabb');
const matchObj = /(a+)(b+)/d.exec('aaaabb');
3.6 Class field declarations
class SampleClass {
/*
instead of:
constructor() { this.publicID = 42; }
*/
publicID = 42; // public field
/*
instead of:
static get staticPublicField() { return -1 }
*/
static staticPublicField = -1;
// static private field
static #staticPrivateField = 'private';
//private methods
#privateMethod() {}
// static block
static {
// executed when the class is created
}
}
参考资料:
网友评论