Skillversitas

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:

  • let and const (replacing var)
  • Arrow functions (=>)
  • Template literals (backticks `)
  • Destructuring assignment
  • Default parameters
  • Classes
  • Modules (import/export)
  • Promises
  • Map, Set, WeakMap, WeakSet
  • for...of loop
  • 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/await
  • Object.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)

  • BigInt
  • globalThis
  • 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.