• 类似Object.groupBy()和Map.groupBy()这样的js新特性你会用吗?
  • 发布于 2个月前
  • 143 热度
    0 评论
JavaScript 作为一门不断发展的语言,每年都会引入新的特性来提升开发体验。
1. Promise.withResolvers()
这个新特性提供了一种更优雅的方式来创建和管理 Promise 的 resolve 和 reject 函数。
// 旧方式
let resolvePromise, rejectPromise;
const promise = new Promise((resolve, reject) => {
  resolvePromise = resolve;
  rejectPromise = reject;
});

// ES2024新方式
const { promise, resolve, reject } = Promise.withResolvers();
// 堆代码 duidaima.com
// 使用示例
async function executeTask() {
  const { promise, resolve } = Promise.withResolvers();
  startAsyncOperation(resolve);
  return promise;
}
这个特性特别适合需要在 Promise 创建时机之外控制其状态的场景,比如实现事件触发器或复杂的异步流程控制。

2. ArrayBuffer.prototype.transfer()
这个方法允许我们高效地转移 ArrayBuffer 的所有权,避免内存复制。
const buffer = new ArrayBuffer(1024);
const transferred = buffer.transfer();
console.log(buffer.byteLength); // 0,原buffer被清空
console.log(transferred.byteLength); // 1024
// 在Web Workers间传输数据时特别有用
worker.postMessage(buffer.transfer());
这个功能在处理大型二进制数据时特别有价值,可以显著提升性能。

3. String.prototype.isWellFormed()和toWellFormed()
这两个方法用于处理字符串中的无效 Unicode 代理对。
const string = 'Hello\uD800World'; // 包含一个孤立的高代理项
console.log(string.isWellFormed()); // false

// 转换为规范形式
const wellFormed = string.toWellFormed(); // 替换无效字符
console.log(wellFormed.isWellFormed()); // true
这对于处理国际化应用和需要严格Unicode合规的场景非常有用。

4. 正则表达式中的v标志
v标志引入了更一致的转义序列规则,使正则表达式更可预测。
// 旧语法可能产生歧义
/\p{ASCII}/u.test('a'); // true
/\p{ASCII}/v.test('a'); // 语法错误,需要使用更明确的语法

// 新语法更加明确
/\p{ASCII_Hex_Digit}/v.test('A'); // true
/[\p{ASCII_Hex_Digit}]/v.test('A'); // true
5. Object.groupBy()和Map.groupBy()
这些新方法提供了一种简洁的方式来对数据进行分组。
const items = [
  { type: 'fruit', name: 'apple' },
  { type: 'vegetable', name: 'carrot' },
  { type: 'fruit', name: 'banana' }
];

const grouped = Object.groupBy(items, item => item.type);
console.log(grouped);
// {
//   fruit: [
//     { type: 'fruit', name: 'apple' },
//     { type: 'fruit', name: 'banana' }
//   ],
//   vegetable: [
//     { type: 'vegetable', name: 'carrot' }
//   ]
// }
6. Atomics.waitAsync()
为 SharedArrayBuffer 提供了异步等待操作的能力。
const shared = new SharedArrayBuffer(4);
const int32 = new Int32Array(shared);

async function waitForChange() {
  const result = await Atomics.waitAsync(int32, 0, 0);
  console.log('Value changed:', result.value);
}

// 在另一个上下文中
Atomics.store(int32, 0, 42);
Atomics.notify(int32, 0);
7. 数组的扩展方法:toSorted(), toReversed(), toSpliced()
这些方法提供了不修改原数组的排序、反转和修改操作。
const numbers = [3, 1, 4, 1, 5];

// 不修改原数组的排序
const sorted = numbers.toSorted();
console.log(numbers); // [3, 1, 4, 1, 5]
console.log(sorted);  // [1, 1, 3, 4, 5]

// 不修改原数组的反转
const reversed = numbers.toReversed();
console.log(numbers); // [3, 1, 4, 1, 5]
console.log(reversed); // [5, 1, 4, 1, 3]

// 不修改原数组的splice操作
const spliced = numbers.toSpliced(1, 2, 6, 7);
console.log(numbers); // [3, 1, 4, 1, 5]
console.log(spliced); // [3, 6, 7, 1, 5]
8. 新的常用数组方法
一些方便的数组操作方法被添加到规范中。
const array = [1, 2, 3, 4, 5];
// 查找最后一个满足条件的元素
const lastEven = array.findLast(x => x % 2 === 0); // 4
// 查找最后一个满足条件的元素的索引
const lastEvenIndex = array.findLastIndex(x => x % 2 === 0); // 3
// 检查数组是否全部相等
const allEqual = [1, 1, 1].every((x, _, arr) => x === arr[0]); // true
这些特性可以帮助我们编写更清晰、更高效的代码,不过,建议在使用这些新特性时使用相应的 polyfill 或转译工具。
用户评论