ES15 Interactive Hub — ECMAScript 2024
Object.groupBy() cho group dữ liệu, Promise.withResolvers cho event-driven, Array.fromAsync, RegExp v flag, String.isWellFormed/toWellFormed cho UTF-16 safety, Atomics.waitAsync non-blocking — toolkit functional + async richer.
Object.groupBy() & Map.groupBy()
Chuyên đề cốt lõi
💡 Khái niệm tóm tắt
Phân nhóm các phần tử của mảng theo key được tính từ callback — thay thế cho pattern reduce + push cồng kềnh.
🤔 Tại sao cần tính năng này?
Group by là thao tác data cực phổ biến (theo category, theo ngày, theo trạng thái...). Trước phải tự viết reduce với object accumulator, dài và dễ sai. ES15 thêm 2 static method chuẩn cho việc này.
// Trước ES15 — tự dùng reduce
var users = [
{ name: 'Lan', age: 25, role: 'dev' },
{ name: 'Nam', age: 30, role: 'pm' },
{ name: 'Hoa', age: 25, role: 'dev' },
];
var byRole = users.reduce(function(acc, u) {
if (!acc[u.role]) acc[u.role] = [];
acc[u.role].push(u);
return acc;
}, {});
console.log(byRole);
// { dev: [Lan, Hoa], pm: [Nam] }// ES15 — Object.groupBy & Map.groupBy
const users = [
{ name: 'Lan', age: 25, role: 'dev' },
{ name: 'Nam', age: 30, role: 'pm' },
{ name: 'Hoa', age: 25, role: 'dev' },
];
const byRole = Object.groupBy(users, u => u.role);
console.log(byRole);
// { dev: [Lan, Hoa], pm: [Nam] }
// Map version — giữ thứ tự key + chấp nhận object/symbol làm key
const byAge = Map.groupBy(users, u => u.age);
console.log(byAge.get(25)); // [Lan, Hoa]
// Group theo dải/điều kiện
const byAdult = Object.groupBy([1, 5, 18, 22, 17], n =>
n >= 18 ? 'adult' : 'minor'
);Bảng Tra Cứu Nhanh ES15
Xem nhanh cấu trúc + copy snippet
Phân nhóm các phần tử của mảng theo key được tính từ callback — thay thế cho pattern reduce + push cồng kềnh.
const users = [
{ name: 'Lan', age: 25, role: 'dev' },
{ name: 'Nam', age: 30, role: 'pm' },
...Tạo Promise và đồng thời lấy ra resolve/reject ở phạm vi ngoài — không cần khai báo biến trước rồi gán trong constructor.
const { promise, resolve, reject } = Promise.withResolvers();
setTimeout(() => resolve("Done!"), 500);
promise.then(console.log);
...Tạo mảng từ async iterable hoặc iterable chứa promise — phiên bản async của Array.from().
async function* gen() {
yield 1; yield 2; yield 3;
}
...Cờ "/v" cho regex hỗ trợ set notation nâng cao: intersection, subtraction giữa các tập Unicode property.
const re = /[\p{L}--\p{ASCII}]/gv;
console.log('café Hello 中文'.match(re));
const han = /[\p{L}&&\p{Script=Han}]/gv;
...Bộ đôi method kiểm tra và sửa chuỗi UTF-16 chứa lone surrogate (ký tự Unicode lỗi) — quan trọng khi nhận dữ liệu từ DB/network có encoding hỏng.
const good = "Xin chào 👋"; // emoji là surrogate pair hợp lệ const bad = "Hello\uD800World"; // lone high surrogate console.log(good.isWellFormed()); // true ...
Phiên bản KHÔNG BLOCK của Atomics.wait — chờ giá trị shared memory thay đổi mà không treo thread. Quan trọng cho main thread browser (không được phép block).
const sab = new SharedArrayBuffer(4); const view = new Int32Array(sab); const result = Atomics.waitAsync(view, 0, 0, 1000); ...