ES3 and ES5 era
Older code often uses var, function scope, callbacks and manual patterns because the language had fewer built-in tools.
JavaScript versions are not only history. They explain why older code looks different, why modern syntax exists and why runtime support must be checked before shipping.
// ES5 style
var name = "User A";
// Modern JavaScript
const user = { name: "User A", tasks: 12 };
const message = `${user.name} has ${user.tasks} tasks.`;
Versions & Runtimes
JavaScript started small, but the language grew into a serious application language. Older tutorials often use var, function constructors and manual string concatenation because those patterns were once the normal way to write JavaScript.
A major turning point was ECMAScript 2015, often called ES6. It introduced the style many developers now think of as modern JavaScript: let, const, arrow functions, classes, template literals, modules and many other features.
Today, ECMAScript evolves through yearly editions and individual proposals. In practice, developers usually think less in edition numbers and more in feature support: can my target browsers or runtime run this syntax?
Older code often uses var, function scope, callbacks and manual patterns because the language had fewer built-in tools.
Modern syntax became mainstream: const, let, modules, classes, template literals and arrow functions.
The language keeps improving through smaller annual updates instead of rare giant releases.
The useful production question is not only which edition exists, but where a feature actually runs.
Examples
const users = [
{ name: "User A", tasks: 12 },
{ name: "User B", tasks: 18 },
];
const activeUsers = users.filter((user) => user.tasks > 0);
for (const user of activeUsers) {
console.log(`${user.name}: ${user.tasks} tasks`);
}
var users = [{ name: "User A", tasks: 12 }];
for (var i = 0; i < users.length; i++) {
console.log(users[i].name + ": " + users[i].tasks + " tasks");
}
// This can still work, but it is not automatically the best style today.
Rules that matter
Modern JavaScript is powerful, but support is never automatic. Choose syntax, APIs and tooling based on the environments that must run the code.
Use const, let, template literals, modules and array methods as the normal baseline.
You will still meet var, prototypes and callbacks in older projects and libraries.
A feature is not production-ready just because someone wrote a blog post about it.
A browser project, Node project and embedded webview may support different language features.
Transpilers can turn modern syntax into older JavaScript, but they add complexity.
Before using newer syntax broadly, check the environments that must run it.
Production thinking
Version awareness prevents cargo-cult programming. You understand why old code looks old, why modern code is cleaner and why support checks matter before release.
If unsupported syntax breaks a script, accessibility features written in JavaScript may fail too. Runtime support is part of inclusive delivery.
Production teams should define target browsers and runtime versions. Without that baseline, every feature choice becomes guesswork.
Broken JavaScript can hurt navigation, rendered content and user engagement. Version choices should not make important content fragile.
Live code lab
The preview runs inside an isolated iframe. The JavaScript is placed inside the HTML editor for now, so every example stays together and remains easy to understand.
Mini assignment
Practice assignment
Try it yourself
Self-check
Answer these questions before moving on. Versions and runtimes look theoretical until they break a real page.