ECMAScript 2026 — bản đặc tả JavaScript thứ 17, được Ecma phê duyệt vào tháng 6/2026 — mang tới 7 tính năng mới mà không thêm bất kỳ cú pháp nào. Cả 7 đều thay thế những hàm helper mà gần như codebase nào cũng tự viết: upsert cho Map, giữ nguyên số lớn khi parse JSON, cộng số thực chính xác hơn.
Vì sao tin này đáng đọc
ES2026 là bản “dọn dẹp”: mỗi tính năng lấp một khoảng trống nhỏ nhưng gặp hằng ngày. Không có cú pháp mới nên chỉ cần kiểm tra typeof và dùng polyfill khi thiếu.
Upsert cho Map: getOrInsert() và getOrInsertComputed()
Nhóm key theo giá trị vốn cần has(), set() rồi get(). ES2026 gộp cả ba bước thành một lệnh, luôn trả về giá trị cuối cùng trong Map. Bản getOrInsertComputed() chỉ gọi callback khi key chưa tồn tại, nên hợp khi giá trị mặc định tốn chi phí tạo.
const counts = new Map();for (const word of ["a", "b", "a"]) { counts.set(word, counts.getOrInsert(word, 0) + 1);}// Map(2) { 'a' => 2, 'b' => 1 }const groups = new Map();groups.getOrInsertComputed("fruit", () => []).push("apple");groups.getOrInsertComputed("fruit", () => []).push("pear");
JSON giữ nguyên số lớn với context.source và JSON.rawJSON()
JSON.parse() âm thầm làm tròn số nguyên quá lớn: 12345678901234567890 thành 12345678901234567000. ES2026 truyền thêm đối tượng context cho hàm reviver, trong đó context.source giữ đúng chuỗi gốc để chuyển thành BigInt. Chiều ngược lại, JSON.rawJSON() tạo giá trị mà JSON.stringify() xuất nguyên văn, nên BigInt đi trọn vòng JSON.
const json = '{"id": 12345678901234567890}';const data = JSON.parse(json, (key, value, context) => key === "id" ? BigInt(context.source) : value);// data.id === 12345678901234567890nconst payload = { id: JSON.rawJSON("12345678901234567890") };JSON.stringify(payload); // {"id":12345678901234567890}
Iterator.concat() nối các iterator mà không sao chép
Sau các helper map, filter, take của ES2025, ES2026 bổ sung cách chạy nối tiếp nhiều iterator: Iterator.concat() nhận nhiều iterable và trả về một iterator duy nhất, chỉ mở nguồn tiếp theo khi nguồn trước cạn. Lưu ý: mọi đối số phải là đối tượng iterable, truyền chuỗi thô sẽ ném TypeError.
const all = Iterator.concat([1, 2], new Set([3]));console.log([...all]); // [ 1, 2, 3 ]
Uint8Array: Base64 và hex không cần thư viện
Trước đây, btoa() và atob() chỉ làm việc với “binary string”, nên đổi byte thật sang Base64 phải tự viết vòng lặp. ES2026 thêm toBase64(), fromBase64(), toHex(), fromHex() trực tiếp trên Uint8Array, kèm tùy chọn alphabet base64url cho JWT và omitPadding để bỏ dấu “=”. Dữ liệu không hợp lệ sẽ ném SyntaxError.
const bytes = new TextEncoder().encode("Hi!");bytes.toBase64(); // "SGkh"bytes.toHex(); // "486921"Uint8Array.fromBase64("SGkh"); // Uint8Array(3) [ 72, 105, 33 ]
Math.sumPrecise(), Error.isError() và Array.fromAsync()
Math.sumPrecise() cộng dãy số với độ chính xác vô hạn, chỉ làm tròn một lần ở cuối: [1e20, 0.1, -1e20] cho ra 0.1 thay vì 0 như reduce. Error.isError() nhận diện lỗi thật kể cả ở realm khác như iframe hay Node vm, nơi instanceof Error trả về false. Array.fromAsync() là bản async của Array.from(): gom async iterable thành mảng, await từng giá trị lần lượt.
Math.sumPrecise([1e20, 0.1, -1e20]); // 0.1Error.isError(new TypeError("Bad input")); // trueawait Array.fromAsync([Promise.resolve(1), 2]); // [ 1, 2 ]
Lưu ý: Temporal và using không thuộc ES2026
Nhiều bài viết liệt kê Temporal và using vào ES2026, nhưng cả hai đều chốt stage 4 sau khi bản đặc tả đã đóng — TC39 xếp chúng vào ES2027.
Điều này có ý nghĩa gì với bạn
Nâng cấp dần từng helper: chỗ nào đang tự viết get-or-set cho Map, parse JSON id lớn, nối iterator hay convert Base64 thì thay bằng API chuẩn. Lưu ý hỗ trợ: getOrInsert cần Chrome 145/Node 26, Iterator.concat cần Chrome 146, Math.sumPrecise chưa có trên Node.
Bài viết liên quan
- Temporal “về đích”: JavaScript cuối cùng cũng có API xử lý ngày giờ chuẩn — dùng được ngay trên Chrome, Firefox và Node 26
- Công cụ JavaScript đang được “viết lại” bằng Rust: Biome, Rspack, Oxc — nên bắt đầu từ đâu?
- Node.js 26.10.0 ra mắt: crypto.parsePKCS12(), fs.openAsBlobSync(), util.throttle()/debounce() và cải tiến SQLite
Câu hỏi thường gặp
ES2026 có cú pháp mới nào không?
Không. Cả 7 đều là phương thức mới trên các đối tượng có sẵn.
Dùng được ngay hôm nay không?
Tùy tính năng: Array.fromAsync và JSON.rawJSON đã có từ lâu; ba tính năng còn lại cần trình duyệt hoặc Node mới nhất.
Temporal có phải tính năng ES2026 không?
Không. Temporal chốt stage 4 sau khi ES2026 đã đóng; TC39 xếp nó và using vào ES2027.
💬 Tin này ảnh hưởng tới dự án của bạn thế nào? Chia sẻ góc nhìn của bạn trong phần bình luận — mình đọc hết và sẽ tổng hợp những ý hay nhất.
Nguồn tham khảo
Harshal V. Ladhe — “What’s New in ES2026: Every Feature Explained” (11/11/2026)
