JavaScript Versions

JavaScript has undergone considerable development since its inception in 1995. Familiarizing yourself with its version history is essential for crafting contemporary and efficient code, as well as for understanding which features are accessible in various environments. In this discussion, we will delve into the transformation of JavaScript from a basic scripting language into one of the most robust programming languages in existence today.

The History of JavaScript

JavaScript was developed by Brendan Eich while working at Netscape in the year 1995. Initially referred to as "Mocha," it was subsequently named "LiveScript" before ultimately being rebranded as JavaScript upon its release with Netscape Navigator 2.0.

In 1997, JavaScript was formalized as ECMAScript (ES) by ECMA International. This standardization guaranteed that all web browsers would be able to implement JavaScript in a uniform manner.

Important Terms:

  • ECMAScript: The standard specification that defines JavaScript
  • JavaScript: The most popular implementation of ECMAScript
  • ES6, ES2015, ES2016...: Different versions of the ECMAScript standard
  • Understanding Version Names

Prior to 2015: Versions were designated with numbers (ES1, ES2, ES3, ES5)

Subsequent to 2015: Versions are identified by the year of release (ES2015, ES2016, ES2017...)

For example:

  • ES6 = ECMAScript 2015 (same version, two names)
  • ES7 = ECMAScript 2016
  • ES8 = ECMAScript 2017

This alteration in naming assists in recognizing the timeline of feature introductions.

Major JavaScript Versions

ES1 (1997) -The Beginning

The first official JavaScript standard that defined:

  • Basic variables and data types
  • Functions
  • Control flow (if-else, loops)
  • Objects and arrays
  • Example
    
    // Basic ES1 features still work today
    var greeting = "Hello";
    function sayHello() {
        return greeting + " World!";
    }
    console.log(sayHello());
    

    ES2 (1998) - Minor Update

Minor enhancements are intended to align the standard more closely with global benchmarks. There will be no significant feature introductions.

ES3 (1999) - Major Milestone

Introduced features we still use every day:

Regular Expressions

Example

var pattern = /hello/i;
var text = "Hello World";
console.log(pattern.test(text));  // Output: true

Try/Catch Error Handling

Example

try {
    var result = riskyOperation();
    console.log(result);
} catch (error) {
    console.log("Error occurred: " + error.message);
}

Better String Methods

Example

var name = "  JavaScript  ";
console.log(name.trim());  // Output: "JavaScript"

ES4 - Never Released

This iteration was intended but ultimately scrapped because of conflicts regarding the language's future trajectory. The concepts introduced in ES4 had a significant impact on subsequent versions.

ES5 (2009) - Modern Foundation

Following a decade-long hiatus, ES5 reintroduced JavaScript to the contemporary landscape:

Strict Mode

Example

"use strict";
x = 10;  // Error: x is not defined
// Strict mode prevents common mistakes

Array Methods

Example

var numbers = [1, 2, 3, 4, 5];

// forEach - loop through array
numbers.forEach(function(num) {
    console.log(num);
});

// filter - get elements that match condition
var evenNumbers = numbers.filter(function(num) {
    return num % 2 === 0;
});
console.log(evenNumbers);  // Output: [2, 4]

// map - transform each element
var doubled = numbers.map(function(num) {
    return num * 2;
});
console.log(doubled);  // Output: [2, 4, 6, 8, 10]

JSON Support

Example

var person = { name: "Rahul", age: 25 };

// Convert object to JSON string
var jsonString = JSON.stringify(person);
console.log(jsonString);  // Output: {"name":"Rahul","age":25}

// Convert JSON string back to object
var personObject = JSON.parse(jsonString);
console.log(personObject.name);  // Output: Rahul

ES6 / ES2015 - The Game Changer

The most significant update in the history of JavaScript! This release brought forth features that revolutionized our approach to writing JavaScript:

Let and Const

Example

// let - block-scoped variable
let age = 25;
age = 26;  // Can be changed

// const - block-scoped constant
const name = "Yshakan";
// name = "Vikram";  // Error: cannot reassign const

Arrow Functions

Example

// Traditional function
var add = function(a, b) {
    return a + b;
};

// Arrow function - shorter syntax
const addArrow = (a, b) => a + b;

console.log(addArrow(5, 3));  // Output: 8

Template Literals

Example

var name = "Abdul";
var age = 30;

// Old way with concatenation
var message1 = "My name is " + name + " and I am " + age + " years old.";

// New way with template literals
var message2 = `My name is ${name} and I am ${age} years old.`;
console.log(message2);

Classes

Example

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    
    introduce() {
        console.log(`Hi, I'm ${this.name} and I'm ${this.age} years old.`);
    }
}

var person1 = new Person("John", 28);
person1.introduce();  // Output: Hi, I'm John and I'm 28 years old.

Promises

Example

function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("Data loaded successfully!");
        }, 1000);
    });
}

fetchData().then(result => {
    console.log(result);  // Output: Data loaded successfully!
});

Destructuring

Example

// Array destructuring
var colors = ["red", "green", "blue"];
var [first, second] = colors;
console.log(first);   // Output: red
console.log(second);  // Output: green

// Object destructuring
var person = { name: "Vicky", age: 22, city: "Mumbai" };
var { name, city } = person;
console.log(name);  // Output: Vicky
console.log(city);  // Output: Mumbai

Spread Operator

Example

var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
var combined = [...arr1, ...arr2];
console.log(combined);  // Output: [1, 2, 3, 4, 5, 6]

ES2016 / ES7 - Small but Useful

Exponentiation Operator

Example

// Old way
var result1 = Math.pow(2, 3);

// New way
var result2 = 2 ** 3;
console.log(result2);  // Output: 8

Array.includes

Example

var fruits = ["apple", "banana", "orange"];
console.log(fruits.includes("banana"));  // Output: true
console.log(fruits.includes("grape"));   // Output: false

ES2017 / ES8 - Async Made Easy

Async/Await

Example

async function loadData() {
    console.log("Loading...");
    
    // Wait for promise to resolve
    await new Promise(resolve => setTimeout(resolve, 1000));
    
    console.log("Data loaded!");
    return "Complete";
}

loadData().then(result => console.log(result));

String Padding

Example

var num = "5";
console.log(num.padStart(3, "0"));  // Output: 005
console.log(num.padEnd(3, "0"));    // Output: 500

Object.entries

Example

var person = { name: "Arjun", age: 27, city: "Delhi" };

Object.entries(person).forEach(([key, value]) => {
    console.log(`${key}: ${value}`);
});
// Output:
// name: Arjun
// age: 27
// city: Delhi

ES2018 / ES9 - Better Object Handling

Spread for Objects

Example

var person = { name: "Sarah", age: 24 };
var details = { city: "Bangalore", country: "India" };

var fullInfo = { ...person, ...details };
console.log(fullInfo);
// Output: { name: "Sarah", age: 24, city: "Bangalore", country: "India" }

Async Iteration

Example

async function* generateNumbers() {
    yield 1;
    yield 2;
    yield 3;
}

(async function() {
    for await (let num of generateNumbers()) {
        console.log(num);
    }
})();

ES2019 / ES10 - Array Improvements

Array.flat

Example

var nested = [1, [2, 3], [4, [5, 6]]];
console.log(nested.flat());     // Output: [1, 2, 3, 4, [5, 6]]
console.log(nested.flat(2));    // Output: [1, 2, 3, 4, 5, 6]

Array.flatMap

Example

var numbers = [1, 2, 3];
var result = numbers.flatMap(num => [num, num * 2]);
console.log(result);  // Output: [1, 2, 2, 4, 3, 6]

ES2020 / ES11 - Handling Edge Cases

Optional Chaining

Example

var user = {
    name: "Kumar",
    address: {
        city: "Chennai"
    }
};

// Safe access to nested properties
console.log(user?.address?.city);      // Output: Chennai
console.log(user?.contact?.phone);     // Output: undefined (no error!)

Nullish Coalescing

Example

var value1 = null;
var value2 = 0;
var value3 = "";

console.log(value1 ?? "default");  // Output: default
console.log(value2 ?? "default");  // Output: 0
console.log(value3 ?? "default");  // Output: ""

BigInt for Large Numbers

Example

var bigNumber = 9007199254740991n;  // Note the 'n' at the end
var bigger = bigNumber + 1n;
console.log(bigger);  // Output: 9007199254740992n

ES2021 / ES12 - String and Promise Updates

String.replaceAll

Example

var text = "hello world, hello universe";
var newText = text.replaceAll("hello", "hi");
console.log(newText);  // Output: hi world, hi universe

Promise.any

Example

var promise1 = Promise.reject("Error 1");
var promise2 = Promise.resolve("Success!");
var promise3 = Promise.resolve("Also success!");

Promise.any([promise1, promise2, promise3]).then(result => {
    console.log(result);  // Output: Success! (first resolved promise)
});

Numeric Separators

Example

var billion = 1_000_000_000;  // Much easier to read!
console.log(billion);  // Output: 1000000000

ES2022 / ES13 - Class Improvements

Top-Level Await

Example

// Can now use await outside async functions in modules
const data = await fetch('https://api.logic-practice.com/data');
console.log(data);

Private Fields in Classes

Example

class BankAccount {
    #balance = 0;  // Private field
    
    deposit(amount) {
        this.#balance += amount;
    }
    
    getBalance() {
        return this.#balance;
    }
}

var account = new BankAccount();
account.deposit(100);
console.log(account.getBalance());  // Output: 100
// console.log(account.#balance);  // Error: private field

ES2023 / ES14 - Non-Destructive Array Methods

toSorted - Organize without altering the original

Example

var numbers = [3, 1, 4, 1, 5, 9];
var sorted = numbers.toSorted();

console.log(sorted);    // Output: [1, 1, 3, 4, 5, 9]
console.log(numbers);   // Output: [3, 1, 4, 1, 5, 9] (unchanged!)

toReversed - Reverse While Preserving Original

Example

var colors = ["red", "green", "blue"];
var reversed = colors.toReversed();

console.log(reversed);  // Output: ["blue", "green", "red"]
console.log(colors);    // Output: ["red", "green", "blue"] (unchanged!)

findLast - Search from the end of an array

Example

var numbers = [1, 2, 3, 4, 5];
var lastEven = numbers.findLast(num => num % 2 === 0);
console.log(lastEven);  // Output: 4

ES2024 / ES15 - Latest Features

Object.groupBy

Example

var people = [
    { name: "Alice", age: 25 },
    { name: "Bob", age: 30 },
    { name: "Charlie", age: 25 }
];

var grouped = Object.groupBy(people, person => person.age);
console.log(grouped);
// Output: {
//   "25": [{ name: "Alice", age: 25 }, { name: "Charlie", age: 25 }],
//   "30": [{ name: "Bob", age: 30 }]
// }

Promise.withResolvers

Example

var { promise, resolve, reject } = Promise.withResolvers();

setTimeout(() => {
    resolve("Done!");
}, 1000);

promise.then(result => console.log(result));  // Output: Done!

Version Summary Table

Version Year Key Features
ES1 1997 Basic syntax, functions, objects
ES2 1998 Minor improvements
ES3 1999 Regular expressions, try/catch, better strings
ES5 2009 Strict mode, JSON, array methods (map, filter, forEach)
ES6/2015 2015 Let/const, arrow functions, classes, promises, template literals
ES2016 2016 Exponentiation (**), Array.includes()
ES2017 2017 Async/await, Object.entries(), string padding
ES2018 2018 Spread for objects, async iteration
ES2019 2019 Array.flat(), Array.flatMap()
ES2020 2020 Optional chaining (?.), nullish coalescing (??), BigInt
ES2021 2021 String.replaceAll(), Promise.any(), numeric separators
ES2022 2022 Top-level await, private class fields
ES2023 2023 toSorted(), toReversed(), findLast()
ES2024 2024 Object.groupBy(), Promise.withResolvers()

Browser Support

Contemporary Browsers (including Chrome, Firefox, Safari, and Edge) are compatible with the majority of ES6 and later features.

Legacy Browsers might lack support for contemporary functionalities. Consider utilizing:

  • Babel: Transforms modern JavaScript into previous iterations
  • Polyfills: Introduce absent features to older browser versions
  • Feature Detection: Verify the existence of a feature prior to implementation
  • Which Version Should You Learn?

Begin with ES5: Acquire foundational knowledge applicable across all environments

Excel in ES6: Crucial for contemporary development practices

Delve into ES2020+: Discover the latest features as you advance your skills

Conclusion

JavaScript is in a constant state of development, with enhancements introduced annually. The release of ES6 in 2015 marked a significant advancement, bringing forth features that revolutionized JavaScript programming practices. Every subsequent version builds upon its predecessors, enhancing JavaScript's capabilities, improving its readability, and making it more user-friendly for developers.

While you delve into JavaScript, prioritize grasping the fundamental principles before diving into more recent advancements. Every code snippet provided in this tutorial comes with "Try it Yourself" buttons—make use of these to practice and gain hands-on experience!

Prepared to explore further? Let's advance our understanding of JavaScript fundamentals in the upcoming lessons!

Input Required

This code uses input(). Please provide values below: