JavaScript · ES2024

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.

Kinh Nghiệm
0 XP
Hoàn thành khóa học0%

Object.groupBy() & Map.groupBy()

Chuyên đề cốt lõi

Trung bình6 phút

💡 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 (cách viết cũ)Verbose / Cồng kềnh
// 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 (Hiện đại)Tối ưu & Khuyên dùng
// 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ạn đã nắm chắc? Thử chạy code thật hoặc làm trắc nghiệm!

Bảng Tra Cứu Nhanh ES15

Xem nhanh cấu trúc + copy snippet

Object.groupBy() & Map.groupBy()

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' },
...
Promise.withResolvers()

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);
...
Array.fromAsync()

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;
}
...
RegExp v flag (Unicode Sets)

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;
...
String.isWellFormed() & toWellFormed()

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
...
Atomics.waitAsync

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);
...