ES17 Interactive Hub — ECMAScript 2026
Explicit Resource Management (using/await using với Symbol.dispose), Error.isError() cross-realm safe, RegExp pattern modifiers (?i:...) scope flag inline, Iterator.range/zip — nâng cấp ergonomics + an toàn resource management.
Explicit Resource Management (using)
Chuyên đề cốt lõi
💡 Khái niệm tóm tắt
Từ khoá `using` và `await using` tự động dọn dẹp resource khi rời scope thông qua Symbol.dispose / Symbol.asyncDispose — như "with" của Python, "using" của C#.
🤔 Tại sao cần tính năng này?
Pattern dọn resource (đóng file, release lock, close DB connection, abort fetch) trước phải dùng try/finally — verbose, dễ quên, hỗn loạn khi có nhiều resource. ES17 giới thiệu syntax `using x = ...` để JS engine tự gọi x[Symbol.dispose]() khi rời block, kể cả khi throw. `await using` cho async cleanup.
// Trước ES17 — try/finally thủ công, lồng nhau khi nhiều resource
function readFiles() {
const file1 = openFile('a.txt');
try {
const file2 = openFile('b.txt');
try {
const file3 = openFile('c.txt');
try {
return processAll(file1, file2, file3);
} finally {
file3.close();
}
} finally {
file2.close();
}
} finally {
file1.close();
}
}
// Pattern còn tệ hơn với async (cần phải await trong finally)
async function readAsync() {
const conn = await openDB();
try {
const tx = await conn.beginTransaction();
try {
return await tx.query('...');
} finally {
await tx.rollback();
}
} finally {
await conn.close();
}
}// ES17 — using tự gọi dispose khi rời scope
function createResource(name) {
return {
name,
[Symbol.dispose]() {
console.log(`Closing ${name}`);
}
};
}
function readFiles() {
using file1 = createResource('a.txt');
using file2 = createResource('b.txt');
using file3 = createResource('c.txt');
return process(file1, file2, file3);
// → tự động gọi dispose theo thứ tự ngược: file3, file2, file1
// → kể cả khi throw, dispose vẫn chạy
}
// async version với Symbol.asyncDispose
function createAsyncResource(name) {
return {
name,
async [Symbol.asyncDispose]() {
await new Promise(r => setTimeout(r, 10));
console.log(`Async closed ${name}`);
}
};
}
async function readAsync() {
await using conn = createAsyncResource('DB');
await using tx = createAsyncResource('TX');
// ... use them
// → await dispose theo LIFO order khi rời async function
}Bảng Tra Cứu Nhanh ES17
Xem nhanh cấu trúc + copy snippet
Từ khoá `using` và `await using` tự động dọn dẹp resource khi rời scope thông qua Symbol.dispose / Symbol.asyncDispose — như "with" của Python, "using" của C#.
function createResource(name) {
return {
name,
...Static method kiểm tra robust một giá trị có phải Error instance không — hoạt động xuyên realm (iframe, worker, structuredClone) mà `instanceof Error` không xử lý được.
console.log(Error.isError(new Error("ok"))); // true
console.log(Error.isError(new TypeError("ok"))); // true
console.log(Error.isError(new RangeError("ok"))); // true
...Cú pháp `(?i:abc)` và `(?-i:abc)` bật/tắt flag (i, m, s) chỉ trong một phần của regex thay vì toàn bộ — giảm độ phức tạp khi viết regex kết hợp nhiều case sensitivity.
const pattern = /[A-Z]+(?i:end)/;
console.log(pattern.test("HELLOend")); // true
console.log(pattern.test("HELLOEND")); // true
...Hai static method tạo iterator built-in: range(start, end, step) sinh dải số, zip(...iters) ghép song song nhiều iterator — không cần Array.from hay loop tay.
for (const i of Iterator.range(1, 6)) {
console.log(i); // 1, 2, 3, 4, 5
}
...