跪拜 Guibai
← All articles
JavaScript · Interview · Frontend

JavaScript from ES6 to ES2026: What Each Version Actually Changed

By 王林不想说话 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Knowing which feature landed in which version prevents the common mistake of treating all modern JavaScript as “ES6.” It also clarifies what a build tool can fix versus what requires a runtime polyfill or a higher minimum target — a distinction that directly affects bundle size, debugging, and production reliability.

Summary

The JavaScript specification has shipped 12 annual editions since ES2015, each adding a focused set of capabilities. This reference catalogs them all — from block scoping and Promises through Iterator Helpers, Set operations, and the ES2026 additions like Math.sumPrecise and Uint8Array Base64/Hex conversion. Every feature is explained through five lenses: the problem it solves, basic syntax, runtime behavior, practical application, and common misconceptions.

Beyond the API tour, the guide maps features to real workflows: configuration defaults, list transformations, async task selection, module loading, and binary data handling. It distinguishes what can be transpiled, what needs a polyfill, and what — like Proxy or SharedArrayBuffer — cannot be fully emulated in older engines.

The closing sections address the gap between spec ratification and browser availability, the difference between app and library compatibility strategies, and a migration order for teams still working in ES5-era codebases.

Takeaways
ECMAScript versions from ES2016 onward are annual, focused releases, not the massive dump that ES2015 was.
Transpilation rewrites syntax; polyfills supply missing runtime APIs — the two solve different problems and must be assessed separately.
Proxy, WeakRef, SharedArrayBuffer, and private fields cannot be fully polyfilled because they depend on engine internals.
Optional chaining and nullish coalescing are not interchangeable with logical OR; they treat falsy values differently.
async/await is Promise control-flow syntax — it does not provide cancellation, timeouts, or concurrency limits.
ES2023’s toSorted, toReversed, toSpliced, and with return new arrays, making immutable state updates a first-class pattern.
Iterator Helpers (ES2025) enable lazy pipelines that avoid intermediate arrays, but iterators are single-consumption.
ES2026 adds Math.sumPrecise for more stable floating-point summation, Iterator.concat for lazy concatenation, and native Base64/Hex on Uint8Array.
Stage 3 proposals are not production guarantees; only Stage 4 and formal annual inclusion confirm a feature is standard.
Compatibility is a product decision — older targets mean more transform code, more polyfills, and capabilities that cannot be fully replicated.
Conclusions

Framing all modern JavaScript as “ES6” obscures real compatibility questions: a runtime might support arrow functions but not Proxy, or optional chaining but not Iterator Helpers.

The annual release cadence has made the language’s evolution incremental and predictable, but it also means developers must track a moving target rather than waiting for a single big-bang upgrade.

Many features that feel like syntax sugar — optional chaining, nullish coalescing, logical assignment — encode subtle semantic choices that directly affect how bugs manifest in production.

The gap between spec ratification and universal browser support remains years wide for some APIs, making feature detection and progressive enhancement still necessary skills.

JavaScript’s growing binary and concurrency capabilities (SharedArrayBuffer, Atomics, Float16, ArrayBuffer transfer) signal that the language is absorbing workloads once reserved for C++ and WASM, but they come with sharp edges that most business code should avoid.

Concepts & terms
Temporal Dead Zone (TDZ)
The region between entering a scope and the actual declaration of a let/const variable. The binding exists but is uninitialized; accessing it throws a ReferenceError.
Live Binding
An ES module import that reflects the current value of the exported binding, not a snapshot. If the exporting module updates a variable, the importing module sees the new value.
SameValueZero
The comparison algorithm used by Array.prototype.includes and Map/Set key equality. It treats NaN as equal to NaN and does not distinguish +0 from -0.
Well-Formed Unicode String
A string that contains no lone surrogates — unpaired UTF-16 code units in the range 0xD800–0xDFFF. ES2024 added isWellFormed() and toWellFormed() to detect and repair such strings.
Private Brand Check
Using #field in obj to test whether an object was created by a specific class that declares that private field, without triggering a syntax error or property access.
Iterator Helper
A method on the Iterator prototype (ES2025) that enables lazy .map(), .filter(), .take(), .drop(), and .flatMap() chains without materializing intermediate arrays.
AggregateError
The error type thrown by Promise.any when all input promises reject. Its errors property contains an array of the individual rejection reasons.
Null Prototype Object
An object created with Object.create(null) or returned by Object.groupBy. It has no inherited properties like toString or __proto__, avoiding key collisions.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗