Skyphobia

年末大放送:ECMA TC39 和 W3C WICG 近期整活盘点 2021 年决定版

Front-EndECMAScriptTC39W3C

0x00 ES3, ES5, ES….2022?

【史前浏览器大战部分略】

浏览器对于 JavaScript 的实现基于在标准 ECMA-262 中定义的脚本语言规范,即 ECMAScript。制定和维护该标准的的组织是一个所属 Ecma International 名为 TC39 的团体。也就是说,掌握了 ECMAScript 的制定动向,就等于掌握了前端的流行风向标

阅读本文可以让你成为前端最新潮最 in 最 fashion 的仔(2021 暂定版)。

简单地对 TC39 草案的各个阶段作一个说明:

  • Stage 0 / Strawperson:任何想法、讨论都在这个阶段;
  • Stage 1 / Proposal:进一步举例应用场景,提出一些潜在问题和实现方案。
  • Stage 2 / Draft:起草语言层面的语义语法,提供规范初稿,准备正式的规范文档,一般会有 babel 的实现。
  • Stage 3 / Candidate:修修补补的候选阶段,根据社区讨论完善最后落地的规范。
  • Stage 4 / Finished:可以被纳入到正式的 ECMAScript 语言规范中了。

下面会讨论一些新纳入 Stage 4 的规范,稍许带一点 Stage 3,没有 Stage 2,没有 Stage 1。

0x01 W3C WICG

点击这里打开新世界的大门

除开 JavaScript 的标准,其他的 WEB 标准也很重要!除了制订了 HTML 标准的 WHATWGW3C曾经在推动 WEB 发展的过程中起到了至关重要的作用。

虽然 W3C 日渐式微,但其社区团体之一的 WICG 还是时不时会有一些有趣的非标准的草案被浏览器实现。虽然有趣,却完全没有主流标准和兼容性的支撑。so, 下面所有涉及到 W3C WICG 一律不准在生产环境中使用,违者后果自负

1x00 空值合并运算符 Nullish coalescing Operator

状态:Stage 4

🔗 兼容性查询

空值合并运算符的前值为 nullundefined 时输出后值,反之则输出前值。使用 ?? 可以避免查询真值表。

javascript
0 || 1 // 1 undefined || 1 // 1 0 ?? 1 // 0 undefined ?? 1 // 1 null ?? 1 // 1

PS: 附赠逻辑空赋值一枚 ??=

PS: 以及其他逻辑赋值操作符 ||=&&=

01x01 String.prototype.replaceAll

状态:Stage 4

🔗兼容性查询

让我一次 replace 个够:

javascript
const str = '苹果的 CEO 是乔布斯,乔布斯简直碉堡了!' // 过去 str.replace(/乔布斯/g, '库克') // 苹果的 CEO 是库克,库克简直碉堡了! // 现在 str.replaceAll('乔布斯', '库克') // 苹果的 CEO 是库克,库克简直碉堡了!

1x02 Promise.any

状态:Stage 4

🔗兼容性查询

Promise.any 遵循 first to fulfil 原则,只使用第一个成功状态的 promise 来返回。

javascript
const p1 = new Promise((resolve, reject) => { reject('p1: reject') }) const p2 = new Promise((resolve, reject) => { setTimeout(resolve, 100, 'p2: resolve') }) Promise.any([p1, p2]).then(value => { console.log(value) // p2: resolve })

1x03 数字分隔符 Numeric separators

状态:Stage 4

🔗兼容性查询

数字分隔符,主要是为了好看。

javascript
const number = 1_000_000_000_000

1x04 Top-level await

状态:Stage 4

🔗兼容性查询

抛开 async 的束缚,在 funciton 之外也可以使用 await

javascript
// IIFE 解决 await 必须在 async function 作用域内的问题 (async function main () { await fetch('http://foo.bar') })() // Top-level await await fetch('http://foo.bar')

1x05 Class Fields #

状态:Stage 4

🔗兼容性查询

类私有成员变量 / 私有成员方法。

javascript
class Storage { #length = 0 #cache = {} get (key) { return this.#cache[key] } set (key, value) { if (!this.#cache) { this.#length++ } this.#cache[key] = value } length () { return this.#length } }

1x06 ShadowRealm API

状态:Stage 3

这是一个真正令人振奋的标准,尽管它还没有被任何浏览器实现。nodejs 可以通过 vm 库来模拟 ShadowRealm API。

ShadowRealms 提案提供了一种在新的全局对象的上下文中执行 JavaScript 代码的方法,也就是所谓的沙盒环境。

javascript
const realm = new ShadowRealm() const result = realm.evaluate(` function add (a, b) { return a + b } add(2, 3) `) console.log(result) // 5

我们过去创建沙盒的大致思路是,创建一个 iframe 的沙盒,然后通过 eval 在这个沙盒中运行程序,最后销毁 iframe,大致代码如下:

javascript
const iframe = document.createElement('iframe') // 为 iframe 设置 sandbox 属性来创建沙盒 iframe.setAttribute('sandbox', 'allow-same-origin allow-scripts') iframe.style.display = 'none' document.body.parentElement.appendChild(iframe) // 通过 eval 执行代码 const result = iframe.contentWindow.eval(` function add (a, b) { return a + b } add(2, 3) `) console.log(result) // 5 // 移除 iframe iframe.remove()

提到了沙盒,就想到了隔离,提到了隔离,就又想到了微前端 🌛

1x07 Temporal

状态:Stage 3

🔗兼容性查询

一个更现代的日期时间 API,尽管它也没有被任何浏览器实现。

Date 对象放在今天,就跟现在喊新垣结衣老婆一样赶不上时代了。正如男同胞们需要一个安慰,JavaScript 也需要一个 Temporal。

Temporal 草案重新设计了与日期、时间相关的计算接口,支持非公历日期,增强了对时区及夏令时的支持,以及可以解析一个严格规定的字符串格式。

由于目前 Temporal 还在 Stage 3,这里只简单列举一些我们可能常用的 API:

javascript
Temporal.Now.instant() // 获取自 Unix 时间以来的精确时间 e.g: 2021-11-26T10:57:01.500944804Z Temporal.Now.instant().add({ hours: 5 }) // 再加五个钟! const duration = Temporal.Duration.from({ hours: 1, minutes: 120 }) duration.total({ unit: 'second' }) // 10800

2x00 EyeDropper API

非官方标准

🔗兼容性查询

屏幕取色器 API。

试想一下,如果我们想在 webapp 上实现屏幕任意位置取色的功能,我们大概有什么思路去实现呢?

在限制取色范围为页面内部的时候,我们可以利用 html2canvas 将当前页面绘制成 canvas,然后在 canvas 上取色。这么做的问题是:

  • 无法对整个屏幕取色
  • 绘制 canvas 的开销太大
  • 浏览器的 devtool 中明明存在这么个屏幕取色器,为什么我们不能调用它?

也不是真的不能调用它:

javascript
let eyeDropper = new EyeDropper(); const { sRGBHex } = await eyeDropper.open() console.log(sRGBHex)

2x01 uuid

非官方标准

基于 RFC4122 标准生成 uuid v4。

javascript
// 目前的实现方式 function uuidv4 () { return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) ) } // 基于该草案的实现 function uuidv4 () { return crypto.randomUUID() }

2x02 Accelerated Shape Detection in Images

非官方标准

🔗兼容性查询

这个草案中包含了两种可能会用到的 API,一个是人脸识别,一个是条形码识别,不过目前只有条形码识别的部分支持,具体参照兼容性查询。

javascript
const barcodeDetector = new BarcodeDetector() barcodeDetector.detect(theImage) .then(detectedCodes => { for (const barcode of detectedCodes) { console.log(barcode) } }) .catch(() => { console.error('检测失败') })
ADD COMMENT