专栏名称: 奇舞精选
《奇舞精选》是由奇舞团维护的前端技术公众号。除周五外,每天向大家推荐一篇前端相关技术文章,每周五向大家推送汇总周刊内容。
目录
相关文章推荐
北京药监  ·  市药监局高效服务 ... ·  22 小时前  
北京药监  ·  市药监局高效服务 ... ·  22 小时前  
湖北省教育厅  ·  “湖北造”人形机器人集体亮相! ·  2 天前  
湖北省教育厅  ·  “湖北造”人形机器人集体亮相! ·  2 天前  
闽南日报  ·  突发!松下电器将解散 ·  2 天前  
51好读  ›  专栏  ›  奇舞精选

ECMAScript 2024 新特性解读!

奇舞精选  · 公众号  · 科技创业 科技自媒体  · 2024-09-20 17:43

主要观点总结

本文介绍了ECMAScript 2024语言规范的新增内容,包括Well-Formed Unicode Strings、Asynchronous atomic wait for ECMAScript Workers、RegExp v flag with set notation + properties of strings、ArrayBuffer transfer、Array grouping和Promise.withResolvers等提案的细节和地址。

关键观点总结

关键观点1: Well-Formed Unicode Strings提案

引入String.prototype.isWellFormed()方法验证字符串是否格式良好,还提供String.prototype.toWellFormed()辅助方法替换孤立的代理对。

关键观点2: Asynchronous atomic wait for ECMAScript Workers提案

提供一种异步方式实现工作线程的原子等待,可以在主线程上使用。

关键观点3: RegExp v flag with set notation + properties of strings提案

新增RegExp v标志,用于对一组Unicode字符串属性进行检查,执行减法/交集/并集匹配,改善不区分大小写的匹配。

关键观点4: ArrayBuffer transfer提案

引入transfer()和transferToFixedLength()等方法方便地调整ArrayBuffer的大小,还提供detached getter方法检查已释放的缓冲区。

关键观点5: Array grouping提案

将Lodash、Ramda等工具库广泛使用的groupBy方法纳入ECMAScript,作为Object.groupBy/Map.groupBy的静态方法实现。

关键观点6: Promise.withResolvers提案

为语言添加延迟Promise的功能,避免在Promise的执行函数中嵌套过多代码,尤其当需要传递resolve或reject方法给多个调用者时。


正文

大家好,我是 ConardLi

ECMAScript 2024 (https://tc39.es/ecma262/2024/) 语言规范的最终版本于 6 26 日获得批准。今天带大家一起来看一下这个版本新增了哪些走进标准的提案。

提案1:Well-Formed Unicode Strings

JavaScript 中的字符串由一系列 UTF-16 编码点表示。名称中的 16 表示可用于存储编码点的位数,提供了 65536 个可能的组合(216)。这个数量足以存储拉丁、希腊、斯拉夫和东亚文字的字符,但不足以存储中文、日文和韩文表意文字或表情符号等内容。额外的字符以 16 位代码单元的形式存储,称为代理对( surrogate pairs )。

'a'.length
// 1
'a'.split('')
// [ 'a' ]

'🥑'.length
// 2
'🥑'.split('')
//[ '\ud83e', '\udd51' ] 👈 surrogate pair

UTF-16 编码中,前导和尾随代理对的范围是为了避免对单个代码单元字符进行编码的歧义。如果一个代理对缺少前导或尾随代码单元,或者它们的顺序颠倒了,我们将处理一个“孤立代理对”,整个字符串将成为“格式错误”。为了使字符串“格式良好”,它不能包含孤立的代理对。

Well-Formed Unicode Strings 》提案引入了一个 String.prototype.isWellFormed() 方法,用于验证字符串是否格式良好。此外,还提供了一个 String.prototype.toWellFormed() 辅助方法,它将所有孤立的代理对替换为替代字符( U+FFFD , �)。

'\ud83e\udd51'
// 🥑

'\ud83e\udd51'.isWellFormed()
// true

'\ud83e'.isWellFormed() // without trailing surrogate
// false

'\ud83e'.toWellFormed()
// �

提案2:Asynchronous atomic wait for ECMAScript

Workers JavaScript 中实现了多线程。共享内存( SharedArrayBuffer )是一个底层 API ,允许我们在主线程和工作线程之间共享内存进行操作。 Atomics 对象上的一组静态方法可以帮助我们避免读写冲突。

常见的操作是将工作线程置于休眠状态,并在需要时唤醒它。我们可以结合使用 Atomics.wait() Atomics.notify() 方法来实现此操作。然而,这种方法有一些限制,因为 Atomics.wait() 是一个同步 API ,不能在主线程上使用。

Asynchronous atomic wait 》提案提供了一种异步方式来实现此操作,最重要的是,它可以在主线程上进行。

// main thread
let i32a = null;

const w = new Worker("worker.js");
w.onmessage = function (env{
  i32a = env.data;
};

setTimeout(() => {
  Atomics.store(i32a, 01);
  Atomics.notify(i32a, 0);
}, 1000);
// worker thread
const sab = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT);
const i32a = new Int32Array(sab);
postMessage(i32a);

const wait = Atomics.waitAsync(i32a, 00);
// { async: false; value: "not-equal" | "timed-out"; }
// or
// { async: true; value: Promise; }

if (wait.async) {
  wait.value.then((value) => console.log(value));
else {
  console.log(wait.value);
}

提案地址:https://github.com/tc39/proposal-atomics-wait-async

提案3:RegExp v flag with set notation + properties of strings

新的 RegExp v 标志类似于 2015 年添加的支持 Unicode 的正则表达式( u 标志),但功能更加强大。由于与 u 标志的相似性和一些不兼容性,这两个标志不能组合使用。新的 v 正则模式包含了三个功能:对一组 Unicode 字符串属性进行检查,执行减法/交集/并集匹配,并改善不区分大小写的匹配。

// `u`和`v`模式相似,但不能组合使用
const pattern = /./vu;
// SyntaxError: Invalid regular expression: invalid flags

提案地址:https://github.com/tc39/proposal-regexp-v-flag

Unicode 标准定义了一组属性,可以简化正则表达式模式的编写。例如:

  • /\p{Math}/u 用于检查数学运算符
  • /\p{Dash}/u 用于检查破折号标点符号
  • /\p{ASCII_Hex_Digit}/u 用于检查用于表示十六进制数字的符号
const patternMath = /\p{Math}/u;
const patternDash = /\p{Dash}/u;
const patternHex = /\p{ASCII_Hex_Digit}/u;

patternMath.test('+'); // true
patternMath.test('z'); // false

patternDash.test('-'); // true
patternDash.test('z'); // false

patternHex.test('f'); // true
patternHex.test('z'); // false

大多数属性适用于单个字符编码点,但有一些属性,比如 Basic_Emoji、RGI_Emoji RGI_Emoji_Flag_Sequence (以此类推),适用于字符串(多个字符编码点)。

目前,这些类型在 u 模式下不支持,尽管有一些讨论可以改变这种情况。幸运的是,在 v 模式下,我们可以使用 Unicode 字符串属性进行检查。

const pattern = /\p{RGI_Emoji}/u
// SyntaxError: Invalid regular expression: /\p{RGI_Emoji}/u: Invalid property name

const pattern = /\p{RGI_Emoji}/v;

// single codepoint emoji
pattern.test('😀'// true

// multiple codepoints emoji
pattern.test('🫶🏾'// true

v 模式的另一个特性是对字符串属性进行减法( -- )、交集( && )和并集运算。一个值得注意的新特性是在字符类中使用 \q 来表示字符串字面量(多字符字符串)。

匹配除了 💩 之外的所有表情符号:

const pattern = /[\p{RGI_Emoji}--\q{💩}]/v;

pattern.test('😜'// true
pattern.test('💩'// false

仅限大写、十六进制数字安全字符:

const pattern = /[\p{Uppercase}&&\p{ASCII_Hex_Digit}]/v;

pattern.test('f'// true
pattern.test('F'// false

u 模式中,大小写敏感检查的工作方式很令人困惑。当启用忽略大小写标志( i ),并且以反向模式针对特定大小写组( Lowercase_Letter Uppercase_Letter )时,结果并不直观。新的 v 标志使结果更可预测,因此这两个标志不能组合在一起使用。

提案地址:https://github.com/tc39/proposal-is-usv-string

提案4:ArrayBuffer transfer

这项功能主要是为了让我们更方便地调整 ArrayBuffer 的大小。这个提案引入了一些新的方法,例如 transfer() transferToFixedLength() ,它们可以帮助我们在不同的位置之间转移字节。这样我们就可以根据需要将数据迁移到目标位置。

另外,这个提案还引入了一个新的方法,叫做 detached getter 。这个方法的作用是检查已释放的缓冲区,它提供了一种原生的方式来判断一个缓冲区是否已经被释放。

const buffer = new ArrayBuffer();
buffer.detached; // false

const newBuffer = buffer.transfer();
buffer.detached; // true

提案地址:https://github.com/tc39/proposal-arraybuffer-transfer

提案5:Array grouping

数组分组提案,一个由 Lodash、Ramda 和其他工具库广泛使用的 groupBy 方法现在已经成为 ECMAScript 的一部分。

最初的想法是将其实现为 Array.prototype.groupBy ,但这与常用的 Sugar 工具冲突。它被实现为 Object.groupBy / Map.groupBy 的静态方法。

const langs = [
  { name"Rust"compiledtruereleased2015 },
  { name"Go"compiledtruereleased2009 },
  { name"JavaScript"compiledfalsereleased1995 },
  { name"Python"compiledfalsereleased1991 },
];

const callback = ({ compiled }) => (compiled ? "compiled" : "interpreted");
const langsByType = Object.groupBy(langs, callback);

console.log({ langsByType });
// {
//   compiled: [
//     { name: "Rust", compiled: true, released: 2015 },
//     { name: "Go", compiled: true, released: 2009 }
//   ],
//   interpreted: [
//     { name: "JavaScript", compiled: false, released: 1995 },
//     { name: "Python", compiled: false, released: 1991 }
//   ]
// }

https://github.com/tc39/proposal-array-grouping

提案6:Promise.withResolvers

Promise.withResolvers 提案为语言添加了延迟 Promise 的功能,这是一种在 jQuery、bluebird、p-defer 等许多库之前就已经广泛使用的模式。你可以使用它来避免在 Promise 的执行函数中嵌套过多的代码,尤其当你需要将 resolve reject 方法传递给多个调用者时,它的优势就会显现出来。它在处理流或基于事件的系统时尤其有用。







请到「今天看啥」查看全文