JavaScript History and Versions
The Origins of JavaScript
JavaScript was born out of a need at Netscape Communications Corporation in the mid-1990s. At the time, the internet was growing rapidly, and Netscape wanted to create web pages that were more interactive than plain static HTML documents.
Brendan Eich, a programmer at Netscape, was asked to create a programming language for the browser in just 10 days. The language was originally named Mocha, then LiveScript, and finally renamed to JavaScript as a marketing strategy to "ride the wave" of Java's booming popularity at the time.
⚠️ Note: JavaScript is NOT Java. Despite their similar names, they are two very different languages.
ECMAScript Timeline
Here is the timeline of the development of the ECMAScript standard (the standard that governs JavaScript):
ECMAScript 1 (ES1) — 1997
- First release of the ECMAScript standard
- Became the ECMA-262 standard
- The foundations of modern JavaScript were already in place
ECMAScript 2 (ES2) — 1998
- Minor changes to synchronize with the ISO standard
- No significant new features
ECMAScript 3 (ES3) — 1999
- Added regex, try/catch, and improved string handling
- Became the foundation of JavaScript for more than 10 years
ECMAScript 4 (ES4) — Cancelled
- A planned set of major changes that was too ambitious
- Never released due to disagreements between Microsoft and Netscape/Mozilla
ECMAScript 5 (ES5) — 2009
- Strict mode (
"use strict") - JSON support (
JSON.parse,JSON.stringify) - New array methods:
forEach,map,filter,reduce - Getters and Setters
// ES5 example: new Array methods
var students = ["John", "Mike", "Alice", "Emma"];
// forEach
students.forEach(function(name) {
console.log("Student: " + name);
});
// map
var nameUpper = students.map(function(name) {
return name.toUpperCase();
});
console.log(nameUpper); // ["JOHN", "MIKE", "ALICE", "EMMA"]
// filter
var longNames = students.filter(function(name) {
return name.length > 3;
});
console.log(longNames); // ["Alice", "Emma"]
ECMAScript 2015 (ES6) — 2015
The biggest change in JavaScript history:
letandconst(replacingvar)- Arrow functions (
=>) - Template literals (backticks
`) - Destructuring assignment
- Default parameters
- Classes
- Modules (
import/export) - Promises
Map,Set,WeakMap,WeakSetfor...ofloop- Spread operator (
...)
// ES5 vs ES6 comparison
// ES5
var name = "John";
var message = "Hello, " + name + "!";
// ES6
const name2 = "John";
const message2 = `Hello, ${name2}!`;
// ES5: function expression
var add = function(a, b) {
return a + b;
};
// ES6: arrow function
const add2 = (a, b) => a + b;
// ES6: destructuring
const student = {
studentId: "2024100123",
name: "John Smith",
gpa: 3.75
};
const { studentId, name: fullName, gpa } = student;
console.log(studentId); // "2024100123"
console.log(fullName); // "John Smith"
console.log(gpa); // 3.75
ECMAScript 2016 (ES7)
Array.prototype.includes()- Exponentiation operator (
**)
// ES7
const scores = [85, 90, 78, 92, 88];
console.log(scores.includes(90)); // true
// Exponentiation
console.log(2 ** 10); // 1024
ECMAScript 2017 (ES8)
async/awaitObject.entries(),Object.values()- String padding (
padStart,padEnd)
// ES8: async/await
async function fetchStudentData(studentId) {
try {
const response = await fetch(`/api/student/${studentId}`);
const data = await response.json();
return data;
} catch (error) {
console.error("Failed to fetch data:", error);
}
}
// Object.entries
const student = { studentId: "2024100123", name: "John", gpa: 3.75 };
console.log(Object.entries(student));
// [["studentId", "2024100123"], ["name", "John"], ["gpa", 3.75]]
ECMAScript 2018 (ES9)
- Rest/Spread properties
- Asynchronous iteration (
for await...of) - Promise improvements (
Promise.finally)
ECMAScript 2019 (ES10)
Array.prototype.flat(),flatMap()- Object fromEntries
- Optional catch binding
// ES10
const nested = [[1, 2], [3, 4], [5, 6]];
console.log(nested.flat()); // [1, 2, 3, 4, 5, 6]
const entries = [["name", "John"], ["studentId", "2024100123"]];
console.log(Object.fromEntries(entries));
// { name: "John", studentId: "2024100123" }
ECMAScript 2020 (ES11)
BigIntglobalThis- Optional chaining (
?.) - Nullish coalescing (
??) - Dynamic
import() Promise.allSettled()
// ES11
const student = {
name: "John",
address: {
city: "Austin"
}
};
// Optional chaining
console.log(student?.address?.city); // "Austin"
console.log(student?.phone?.city); // undefined (no error!)
// Nullish coalescing
const gpa = null;
console.log(gpa ?? 0); // 0
const gpa2 = 3.75;
console.log(gpa2 ?? 0); // 3.75
ECMAScript 2021 (ES12)
String.prototype.replaceAll()- Promise combinators (
any,allSettled) - Numeric separators (
1_000_000) - Logical assignment operators (
&&=,||=,??=)
ECMAScript 2022 (ES13)
- Top-level
await(in modules) Object.hasOwn()- Class fields and private methods
ECMAScript 2023 (ES14)
- Array grouping methods
- Array
toReversed(),toSorted(),toSpliced()
ECMAScript 2024 (ES15)
- Set methods (
union,intersection,difference) Object.groupBy()- Promise.withResolvers
Case Study: Syntax Evolution in an Academic Portal
Imagine an academic portal development team that has been operating since 2010. The old code still uses ES5, while the new code uses ES6+. Here is the evolution of writing the same code:
ES5 Version (Old Code — 2010)
// Old academic portal code (ES5)
"use strict";
var studentList = [
{ studentId: "2024100123", name: "John Smith", gpa: 3.75 },
{ studentId: "2024100124", name: "Mike Johnson", gpa: 3.50 },
{ studentId: "2024100125", name: "Alice Emma", gpa: 3.90 }
];
function findStudent(studentId) {
for (var i = 0; i < studentList.length; i++) {
if (studentList[i].studentId === studentId) {
return studentList[i];
}
}
return null;
}
function calcAverageGPA() {
var total = 0;
for (var i = 0; i < studentList.length; i++) {
total += studentList[i].gpa;
}
return total / studentList.length;
}
var result = calcAverageGPA();
console.log("Average GPA: " + result);
ES6+ Version (New Code — Today)
// New academic portal code (ES6+)
const studentList = [
{ studentId: "2024100123", name: "John Smith", gpa: 3.75 },
{ studentId: "2024100124", name: "Mike Johnson", gpa: 3.50 },
{ studentId: "2024100125", name: "Alice Emma", gpa: 3.90 }
];
const findStudent = (studentId) =>
studentList.find(m => m.studentId === studentId) ?? null;
const calcAverageGPA = () => {
const total = studentList.reduce((sum, m) => sum + m.gpa, 0);
return total / studentList.length;
};
const averageGPA = calcAverageGPA();
console.log(`Average GPA: ${averageGPA.toFixed(2)}`);
Notice how much more concise and readable the ES6+ code is. This is why upgrading to the latest version of JavaScript is so important.
Summary
| Version | Year | Key Features |
|---|---|---|
| ES1 | 1997 | First release |
| ES3 | 1999 | Regex, try/catch |
| ES5 | 2009 | Strict mode, JSON, Array methods |
| ES6/2015 | 2015 | let/const, arrow, classes, modules |
| ES2017 | 2017 | async/await, Object.entries |
| ES2020 | 2020 | Optional chaining, nullish coalescing |
| ES2024 | 2024 | Set methods, Object.groupBy |
JavaScript continues to evolve with consistent annual releases. Understanding its history helps us appreciate why certain syntax exists and how it has changed over time.