包阅导读总结
1. `ECMAScript 2024`、`新特性`、`前端`、`JavaScript`、`编程`
2. 本文介绍了 ECMAScript 2024 的新增特性,包括字符串格式校验、异步原子等待、正则表达式新功能、ArrayBuffer 转移操作、数组分组和 Promise 的新方法,并对部分特性做了详细说明和示例展示。
3.
– 字符串格式校验
– `String.prototype.isWellFormed()` 方法验证字符串是否格式良好
– `String.prototype.toWellFormed()` 方法处理孤立代理对
– 异步原子等待
– 提供异步方式操作,可在主线程使用
– 正则表达式新功能
– `v` 标志,功能强大,与 `u` 标志不兼容
– 可对 Unicode 字符串属性检查,执行运算,改善不区分大小写匹配
– `ArrayBuffer` 转移操作
– 引入新方法转移字节,判断缓冲区是否释放
– 数组分组
– 以静态方法 `Object.groupBy` 实现
– `Promise` 的新方法
– `Promise.withResolvers` 提供延迟 `Promise` 功能
思维导图:
文章地址:https://mp.weixin.qq.com/s/YCm8BrEkk-3KCXbEMkP6fg
文章来源:mp.weixin.qq.com
作者:ConardLi
发布时间:2024/9/7 23:44
语言:中文
总字数:2652字
预计阅读时间:11分钟
评分:87分
标签:ECMAScript 2024,JavaScript,新特性,字符串处理,异步编程
以下为原文内容
本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com
前言
介绍了 ECMAScript 2024 中新增的几项重要特性,包括字符串格式校验、异步原子等待、正则表达式的新功能、ArrayBuffer 的转移操作、数组分组以及 Promise 的新方法。今日前端早读课文章由 @ConardLi 分享,公号:code 秘密花园授权。
正文从这开始~~
ECMAScript 2024(https://tc39.es/ecma262/2024/)语言规范的最终版本于 6 月 26 日获得批准。今天带大家一起来看一下这个版本新增了哪些走进标准的提案。
【第3203期】ECMAScript 2024(ES15)将带来的新特性
提案 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, 0, 1);
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, 0, 0);
// { async: false; value: "not-equal" | "timed-out"; }
// or
// { async: true; value: Promise<"ok" | "timed-out">; }
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 标准定义了一组属性,可以简化正则表达式模式的编写。例如:
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", compiled: true, released: 2015 },
{ name: "Go", compiled: true, released: 2009 },
{ name: "JavaScript", compiled: false, released: 1995 },
{ name: "Python", compiled: false, released: 1991 },
];
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 方法传递给多个调用者时,它的优势就会显现出来。它在处理流或基于事件的系统时尤其有用。
下面是一个 createEventsAggregator 函数。它返回一个 add 方法来添加新的事件,以及一个 abort 方法用于取消聚合。最重要的是,它返回一个 events Promise,当达到 eventsCount 限制时会被 resolve,当调用 abort 方法时会被 reject。
function createEventsAggregator(eventsCount) {
const events = [];
const { promise, resolve, reject } = Promise.withResolvers();
return {
add: (event) => {
if (events.length < eventsCount) events.push(event);
if (events.length === eventsCount) resolve(events);
},
abort: () => reject("Events aggregation aborted."),
events: promise,
};
}
const eventsAggregator = createEventsAggregator(3);
eventsAggregator.events
.then((events) => console.log("Resolved:", events))
.catch((reason) => console.error("Rejected:", reason));
eventsAggregator.add("event-one");
eventsAggregator.add("event-two");
eventsAggregator.add("event-three");
// Resolved: [ "event-one", "event-two", "event-three" ]
提案地址:https://github.com/tc39/proposal-promise-with-resolvers
【第2993期】ECMAScript 2023 正式发布,有哪些新特性?
关于本文
作者:@ConardLi
原文:https://mp.weixin.qq.com/s/sXQeojB36dAYuYsmS1clfA
这期前端早读课
对你有帮助,帮”赞“一下,
期待下一期,帮”在看” 一下 。