JavaScript ES2025: Các tính năng và patterns dev web cần biết

5 tháng trước · 10 phút đọc
ES2025 là gì - và tại sao bạn không nên học theo checklist
Mình từng mắc cái bẫy này: cứ mỗi năm có ECMAScript mới là lên Google tìm "ES20XX features" rồi đọc hết, nhớ syntax, xong... không biết dùng vào đâu.
Vấn đề là JavaScript không có bước nhảy lớn như ngày xưa ES6 (2015). Từ đó đến nay, TC39 - tổ chức quản lý chuẩn ECMAScript - ra mắt theo từng năm, mỗi năm bundle các proposal đã đạt Stage 4 vào bản chính thức. "ES2025" là tên gọi của edition mới nhất trong chu kỳ này.
Proposal đạt Stage 4 mới vào chuẩn - đừng học Stage 2/3 vội
Thực tế với dev web thì khác hơn lý thuyết một chút: browser, Node.js, và TypeScript thường ship tính năng trước khi edition chính thức được đặt tên. Nên câu hỏi quan trọng hơn là: tính năng này đã chạy được ở runtime mình đang dùng chưa?
Bài này mình sẽ không đi theo kiểu checklist. Thay vào đó, mình chọn những thứ thực sự thay đổi cách viết code trong React/Next.js - cùng với patterns đi kèm để code dễ bảo trì hơn.
Iterator Helpers - lười biếng theo đúng nghĩa
"Lười biếng" (lazy) ở đây là compliment.
Trước ES2025, nếu muốn xử lý một mảng lớn qua nhiều bước - filter, transform, take top 10 - bạn phải tạo mảng trung gian ở mỗi bước. 10.000 phần tử filter còn 500, rồi map ra 500 object mới, rồi slice 10. Ba lần cấp phát bộ nhớ.
Iterator Helpers giải quyết điều này bằng cách chain các thao tác trực tiếp trên iterator, chỉ thực thi khi thực sự cần:
Không có mảng trung gian nào được tạo ra cho đến dòng .toArray(). Các method phổ biến bạn sẽ dùng:
.filter()- lọc theo điều kiện.map()- biến đổi từng phần tử.take(n)- lấy n phần tử đầu.drop(n)- bỏ qua n phần tử đầu.flatMap()- map rồi flatten.toArray()- thu thập kết quả.forEach()- duyệt không thu thập.some()/.every()/.find()- kiểm tra điều kiện.reduce()- tổng hợp
Iterator lazy - không tạo mảng trung gian, chỉ tính khi cần
Dùng trong React thực tế: Khi fetch API trả về danh sách sản phẩm lớn, bạn cần filter theo category và chỉ render 20 sản phẩm đầu tiên. Thay vì:
Với Iterator Helpers:
Trade-off cần biết: Iterator Helpers hoạt động với iterator object, không phải array trực tiếp. Bạn cần gọi .values() hoặc dùng generator. Với mảng nhỏ dưới vài trăm phần tử, chain Array methods truyền thống vẫn ổn và dễ đọc hơn. Dùng Iterator Helpers khi data source thực sự lớn hoặc có thể lazy (stream, generator).
Explicit Resource Management - dọn dẹp theo kiểu người lớn
Bao nhiêu lần bạn viết code kiểu này và quên cleanup?
Explicit Resource Management (hay còn gọi là using declarations) giải quyết vấn đề cleanup bị quên. Đây là pattern mượn từ C# using và Python with:
Với async, dùng Symbol.asyncDispose và await using:
using tự cleanup khi ra scope - không còn lo quên finally
Trong Next.js server code: Pattern này cực kỳ hữu ích cho Route Handlers và Server Actions khi làm việc với DB connection, file handles, hoặc distributed locks:
Trade-off: using declarations cần TypeScript 5.2+ hoặc transpilation. Trong React component, useEffect cleanup vẫn là cách chuẩn cho UI lifecycle - using phù hợp hơn cho non-UI resources ở server-side và utility layers. Đừng cố nhét using vào mọi chỗ.
Patterns đi kèm - phần quan trọng hơn cú pháp
Sự thật là: tính năng ngôn ngữ mới chỉ có giá trị khi bạn biết cách ghép chúng vào workflow thực tế. Dưới đây là các patterns mình thấy quan trọng nhất khi build React/Next.js với JavaScript hiện đại.
Pure functions cho data transforms
Tách logic xử lý data ra khỏi component. Hoàn toàn. Component chỉ lo render:
Lợi ích? Test pure functions không cần mock React, không cần render. Một file test đơn giản là đủ.
Immutable state updates
React detect change bằng reference. Mutate trực tiếp = bug khó tìm:
Patterns quyết định maintainability về lâu dài hơn syntax mới
Typed contracts với TypeScript + Zod
Khi API trả về data, đừng tin blindly. Validate ở runtime:
Zod schema vừa là runtime validation, vừa là TypeScript type - không cần viết hai lần.
Nếu bạn muốn nắm JavaScript vững hơn để áp dụng các pattern này, khóa Lập Trình JavaScript Nâng Cao trên F8 cover khá sâu về closure, reference types và cách JS thực sự hoạt động - foundation tốt trước khi đi vào ES2025.
Áp dụng trong Next.js App Router
Next.js App Router (từ Next.js 13+) mở ra ranh giới rõ ràng giữa Server Components và Client Components. JavaScript ES2025-era features phát huy tốt nhất ở đâu trong kiến trúc này?
Server Components là nơi an toàn nhất để dùng tính năng mới nhất. Runtime Node.js trên server luôn mới hơn browser, không cần lo polyfill:
Server Actions với Explicit Resource Management:
Server vs Client boundary - dùng tính năng mới thoải mái hơn ở server
Client Components cần cẩn thận hơn với browser support. Kiểm tra MDN compatibility trước khi dùng tính năng mới ở đây, hoặc để transpiler (Babel/SWC) lo:
Rule đơn giản: Server = dùng thoải mái. Client = verify support hoặc để transpiler lo.
Nếu bạn đang học React từ đầu hoặc muốn có nền tảng vững cho App Router, khóa Xây Dựng Website với ReactJS cover từ cơ bản đến nâng cao, phù hợp trước khi đi sâu vào Next.js.
Ecosystem đi kèm - đừng dùng mình JavaScript thuần
Modern JS features mạnh hơn khi kết hợp đúng thư viện. Đây là những gì mình thực sự dùng trong production:
| Thư viện | Dùng cho | Ghi chú |
|---|---|---|
| TypeScript | Type safety, refactor an toàn | Bắt buộc với team lớn |
| Zod | Runtime validation, schema-first types | Thay thế joi/yup cho TypeScript projects |
| React Hook Form | Form state + validation | Tích hợp tốt với Zod qua resolver |
| TanStack Query | Server state caching, retry, sync | Giảm boilerplate fetch/loading/error |
| Immer | Immutable updates dễ đọc | Đặc biệt hữu ích với state phức tạp nested |
| Vitest | Test pure functions, utility code | Nhanh hơn Jest, tích hợp tốt với Vite/Next.js |
Bộ công cụ này giúp JS hiện đại phát huy tối đa trong React/Next.js
Một điểm quan trọng về Lodash: nhiều helper của Lodash giờ không cần nữa nhờ native JS đã đủ mạnh. _.map, _.filter, _.find, _.flatten - tất cả đã có native equivalent. Chỉ giữ Lodash khi bạn cần _.debounce, _.throttle, _.cloneDeep, hay các utility phức tạp mà native chưa cover.
Dùng lodash-es thay vì lodash nếu bạn dùng ES modules - bundle size nhỏ hơn đáng kể nhờ tree-shaking.
Takeaways:
- Iterator Helpers giúp xử lý data lớn không cần mảng trung gian - dùng ở server hoặc generator pipeline
- Explicit Resource Management (
using) giúp cleanup tự động, phù hợp cho server-side utilities - Patterns như pure functions + immutable updates + typed contracts quan trọng hơn việc biết từng tính năng mới
- Server Components là nơi an toàn nhất để thử nghiệm ES2025 features
- Ecosystem (TypeScript, Zod, TanStack Query) nhân đôi giá trị của modern JS
Bước tiếp theo thực tế: chọn một dự án đang có, refactor một module data-processing theo pure functions + typed schema. Không cần rewrite toàn bộ - cải thiện từng phần nhỏ. Comment cho mình biết bạn gặp khó khăn ở bước nào nhé.
