JavaScript and ECMAScript are effectively the same thing — ECMAScript is the standardized specification, JavaScript is the name most people actually use for implementations of it — and the version history explains a lot about why some code looks so different from other code.
The Early, Slow Years
ES3 (1999) was JavaScript’s baseline for over a decade. ES4 was abandoned entirely due to disagreements about its scope. ES5 (2009) finally added strict mode, JSON support, and array methods like forEach and map.
ES6/ES2015: The Big One
Arrow functions, classes, let/const, template literals, destructuring, Promises, modules — ES2015 modernized the language more in one release than the previous fifteen years combined, and remains the dividing line most developers mean when they say “modern JavaScript.”
Yearly Releases Since
Starting with ES2016, the language moved to a yearly release cadence with smaller, incremental additions — async/await (ES2017), spread/rest for objects (ES2018), optional chaining (ES2020), top-level await (ES2022). This steady cadence is why “which JavaScript features can I use” became a genuinely important, ongoing question for anyone supporting older browsers.