ECMAScript日常总结–ES2024(ES15)
文章目录
- ECMAScript日常总结--ES2024(ES15)
- 1. 记录(Record)和元组(Tuple)
- 2. 异步上下文(Async Context)
- 3. 增强的错误处理
- 4. 新的正则表达式特性
- 5. 弱化引用集合和映射(WeakRefs和FinalizationRegistry)
- 6. 新的 Set 方法
- 7. 新的 Number 方法
- 8. 逻辑赋值运算符(`&&=`,`||=` 和 `??=`)
- 9. 对象分组 Object.groupBy()
- 10. String.prototype.isWellFormed 和 toWellFormed
- 11. String.prototype.replaceAll
- 12. String.prototype.at
- 13.Promise.withResolvers
1. 记录(Record)和元组(Tuple)
描述:
记录和元组是新的不可变数据结构。记录类似于对象,而元组类似于数组。
在 Vue.js 中的示例:
<script setup>
import { ref } from 'vue';
// 定义一个不可变的记录
const userRecord = #{ name: "A", age: 30 };
// 定义一个不可变的元组
const scoresTuple = #[10, 20, 30];
const user = ref(userRecord); // 使用 ref 创建一个响应式记录
const scores = ref(scoresTuple); // 使用 ref 创建一个响应式元组
console.log(user.value); // 输出记录:#{ name: "A", age: 30 }
console.log(scores.value); // 输出元组:#[10, 20, 30]
</script>
解释:
#{ ... }
和#[ ... ]
分别用于定义记录和元组,这些数据结构是不可变的。ref
用于将记录和元组包装成响应式数据,以便在 Vue.js 组件中使用。
2. 异步上下文(Async Context)
描述:
异步上下文特性允许在异步代码中传递上下文信息,而无需手动传递参数。
在 Vue.js 中的示例:
<script setup>
import { ref, onMounted } from 'vue';
// 定义一个响应式变量来保存异步上下文
const asyncContext = ref(null);
// 异步函数来模拟数据获取
async function fetchData() {
await new Promise(resolve => setTimeout(resolve, 1000)); // 模拟1秒的异步操作
asyncContext.value = { data: 'Fetched Data' }; // 更新上下文
}
// 组件挂载时调用异步函数
onMounted(() => {
fetchData();
});
console.log(asyncContext.value); // 初始输出为 null,一秒后输出 { data: 'Fetched Data' }
</script>
解释:
ref
用于创建一个响应式变量asyncContext
。fetchData
是一个模拟异步操作的函数,完成后更新asyncContext
的值。onMounted
确保在组件挂载后调用fetchData
。
3. 增强的错误处理
描述:
新的错误处理特性提供了更好的错误信息和更灵活的错误捕获机制。
在 Vue.js 中的示例:
<script setup>
try {
// 一些可能抛出错误的代码
throw new Error('Something went wrong');
} catch (error) {
console.error('错误信息:', error.message); // 输出错误信息
console.error('错误堆栈:', error.stack); // 输出错误堆栈
}
</script>
解释:
try...catch
块用于捕获并处理异常。error.message
和error.stack
提供了详细的错误信息和堆栈信息。
4. 新的正则表达式特性
描述:
ES2024 增强了正则表达式的功能,包括新的修饰符和更好的性能。
在 Vue.js 中的示例:
<script setup>
// 使用 's' 修饰符,表示点号(.)可以匹配换行符
const regex = /foo.bar/s;
const text = 'foo\nbar';
const match = text.match(regex);
console.log(match); // 输出: [ 'foo\nbar', index: 0, input: 'foo\nbar', groups: undefined ]
</script>
解释:
s
修饰符允许正则表达式中的.
匹配换行符。match
方法根据正则表达式查找匹配的文本。
5. 弱化引用集合和映射(WeakRefs和FinalizationRegistry)
描述:
WeakRefs 允许你持有一个对象的弱引用,不会阻止垃圾回收。FinalizationRegistry 允许在对象被垃圾回收时执行回调。
在 Vue.js 中的示例:
<script setup>
import { ref } from 'vue';
const weakMap = new WeakMap();
const obj = { name: 'A' };
weakMap.set(obj, 'Some value');
// 弱引用,不会阻止 obj 被垃圾回收
const weakRef = new WeakRef(obj);
console.log(weakRef.deref()); // 输出: { name: 'A' }
const registry = new FinalizationRegistry(heldValue => {
console.log('对象已被垃圾回收:', heldValue);
});
// 注册对象,当对象被垃圾回收时,执行回调
registry.register(obj, '与A相关的清理');
obj = null; // obj 现在可以被垃圾回收
</script>
解释:
WeakRef
和FinalizationRegistry
提供了对对象的弱引用管理和垃圾回收后的清理功能。- 当对象被垃圾回收时,注册的回调函数会被调用。
6. 新的 Set 方法
描述:
增加了几个新的 Set 方法,如 Set.prototype.intersection
,Set.prototype.difference
,和 Set.prototype.union
,用于集合的交集、差集和并集操作。
在 Vue.js 中的示例:
<script setup>
import { ref } from 'vue';
const setA = new Set([1, 2, 3, 4]);
const setB = new Set([3, 4, 5, 6]);
// 计算集合的交集
const intersection = ref(setA.intersection(setB));
console.log(intersection.value); // 输出: Set { 3, 4 }
// 计算集合的差集
const difference = ref(setA.difference(setB));
console.log(difference.value); // 输出: Set { 1, 2 }
// 计算集合的并集
const union = ref(setA.union(setB));
console.log(union.value); // 输出: Set { 1, 2, 3, 4, 5, 6 }
</script>
解释:
intersection
返回两个集合的交集。difference
返回两个集合的差集。union
返回两个集合的并集。
7. 新的 Number 方法
描述:
新增了一些 Number 方法,如 Number.range
,用于生成数字范围。
在 Vue.js 中的示例:
<script setup>
import { ref } from 'vue';
// 生成一个范围为 [0, 10) 的数字序列
const numberRange = Number.range(0, 10);
const numbers = ref([]);
for (let num of numberRange) {
numbers.value.push(num);
}
console.log(numbers.value); // 输出: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
</script>
解释:
Number.range
用于生成指定范围的数字序列。- 使用
for...of
循环遍历生成的范围,并将数字添加到响应式数组中。
8. 逻辑赋值运算符(&&=
,||=
和 ??=
)
描述:
逻辑赋值运算符(&&=
,||=
和 ??=
)使得条件赋值更加简洁。
在 Vue.js 中的示例:
<script setup>
import { ref } from 'vue';
let count = ref(0);
let value = ref(null);
// 仅在 count 非零时赋值
count.value &&= 10;
console.log(count.value); // 输出: 0
// 仅在 value 为 null 或 undefined 时赋值
value.value ??= 'default';
console.log(value.value); // 输出: 'default'
</script>
let userName = ref('');
let userAge = ref(null);
let userStatus = ref('');
// 使用 ||= 运算符
userName.value ||= 'A'; // userName.value 是空字符串,赋值为 'A'
userAge.value ||= 18; // userAge.value 是 null,赋值为 18
userStatus.value ||= 'B'; // userStatus.value 是空字符串,赋值为 'B'
// 输出结果
console.log(userName.value); // 输出: 'A'
console.log(userAge.value); // 输出: 18
console.log(userStatus.value); // 输出: 'B'
解释:
&&=
仅在左侧值为真时才进行赋值。??=
仅在左侧值为 null 或 undefined 时才进行赋值。||=
仅在左侧值为假值(如null
、undefined
、0
、false
、NaN
或空字符串)时才进行赋值操作。
9. 对象分组 Object.groupBy()
描述:
对象分组特性允许根据对象的属性对数组进行分组。
在 Vue.js 中的示例:
<script setup>
import { ref } from 'vue';
const people = ref([
{ name: 'A', age: 30 },
{ name: 'B', age: 25 },
{ name: 'C', age: 30 },
{ name: 'D', age: 25 }
]);
// 根据年龄分组
const groupedByAge = people.value.groupBy(person => person.age);
console.log(groupedByAge);
// 输出: { 30: [{ name: 'A', age: 30 }, { name: 'C', age: 30 }], 25: [{ name: 'B', age: 25 }, { name: 'D', age: 25 }] }
</script>
解释:
groupBy
方法根据回调函数的返回值对数组元素进行分组。- 在示例中,按照
age
属性对people
数组进行分组。
10. String.prototype.isWellFormed 和 toWellFormed
描述:
这些方法用于检测和修复字符串中的无效 Unicode 序列。
在 Vue.js 中的示例:
<script setup>
import { ref } from 'vue';
const invalidString = ref('\uD800'); // 仅包含高位代理对
// 检查字符串是否是格式良好的 Unicode
const isWellFormed = invalidString.value.isWellFormed();
console.log(isWellFormed); // 输出: false
// 修复无效的 Unicode 序列
const wellFormedString = invalidString.value.toWellFormed();
console.log(wellFormedString); // 输出: '\uFFFD'(替换字符)
</script>
解释:
isWellFormed
方法用于检测字符串是否包含无效的 Unicode 序列。toWellFormed
方法用于修复字符串中的无效 Unicode 序列,将其替换为 Unicode 替换字符。
11. String.prototype.replaceAll
描述:
String.prototype.replaceAll
方法用于替换所有匹配的子字符串,而不是仅替换第一个匹配项。
在 Vue.js 中的示例:
<script setup>
import { ref } from 'vue';
const text = ref('Hello World! Hello Everyone!');
// 替换所有匹配的子字符串
const newText = text.value.replaceAll('Hello', 'Hi');
console.log(newText); // 输出: 'Hi World! Hi Everyone!'
</script>
解释:
replaceAll
方法用于替换字符串中所有匹配的子字符串。- 在示例中,所有的
Hello
都被替换为Hi
。
12. String.prototype.at
描述:
String.prototype.at
方法用于根据索引值获取字符串中的字符,可以使用负索引值从字符串末尾开始。
在 Vue.js 中的示例:
<script setup>
import { ref } from 'vue';
const text = ref('Hello World!');
// 使用正索引值获取字符
const charAtIndex5 = text.value.at(5);
console.log(charAtIndex5); // 输出: ' '
// 使用负索引值获取字符
const charAtIndexMinus1 = text.value.at(-1);
console.log(charAtIndexMinus1); // 输出: '!'
</script>
解释:
at
方法根据索引值获取字符串中的字符。- 负索引值可以从字符串末尾开始获取字符。
13.Promise.withResolvers
描述:
Promise.withResolvers
简化了创建和管理 promise 的流程。它允许你同时创建一个 promise 和与其关联的 resolver 对象,从而可以更方便地在不同的上下文中解决或拒绝该 promise。
- 简化代码:不再需要手动创建 resolver 函数,减少了样板代码。
- 提高可读性:明确地将 promise 和 resolver 对象关联在一起,代码更加清晰。
- 方便管理异步操作:特别适用于需要在多个地方处理 promise 的场景,如事件处理、回调等。
Promise.withResolvers
返回一个对象,该对象包含两个属性:
promise
- 代表异步操作的 promise 对象。resolvers
- 一个包含resolve
和reject
方法的对象,用于解决或拒绝这个 promise。
在 Vue.js 中的示例:
const { promise, resolvers } = Promise.withResolvers();
promise.then(value => {
console.log('Promise resolved with:', value);
}).catch(error => {
console.error('Promise rejected with:', error);
});
// 在不同的上下文中解决或拒绝 promise
setTimeout(() => {
resolvers.resolve('Hello, world!');
}, 1000);
// 或者
setTimeout(() => {
resolvers.reject(new Error('Something went wrong'));
}, 1000);
使用 Promise.withResolvers
创建了一个 promise 以及与其关联的 resolver 对象。在不同的上下文中使用 resolvers.resolve
和 resolvers.reject
方法来解决或拒绝这个 promise。