jsnotes

Topic 005: ES5, ES6, ES7, ES8 features in JS

Topic 005: ES5, ES6, ES7, ES8 features in JS


ES5 features

ECMAScript 5 (ES5) was introduced in December 2009. It brought several significant improvements and new features to the JavaScript language, including strict mode, new object methods, array methods, JSON support, and more. Here are some of the key features introduced in ES5, along with example code snippets for each:

1. Strict Mode

Strict mode is a way to opt into a restricted variant of JavaScript, which helps catch common coding errors and “unsafe” actions.

"use strict";

function myFunction() {
  // Code here runs in strict mode
  var x = 3.14; // Allowed
  y = 3.14; // Error: y is not defined
}
myFunction();

2. Object Methods

New methods for creating, defining properties, and manipulating objects were added.

var person = {
  firstName: "John",
  lastName: "Doe",
};

// Object.create()
var newPerson = Object.create(person);
console.log(newPerson.firstName); // John

// Object.defineProperty()
Object.defineProperty(person, "age", {
  value: 30,
  writable: true,
  enumerable: true,
  configurable: true,
});
console.log(person.age); // 30

// Object.keys()
console.log(Object.keys(person)); // ["firstName", "lastName", "age"]

3. Array Methods

Several useful array methods were added in ES5.

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

// forEach
numbers.forEach(function (num) {
  console.log(num); // 1 2 3 4 5
});

// map
var squares = numbers.map(function (num) {
  return num * num;
});
console.log(squares); // [1, 4, 9, 16, 25]

// filter
var evens = numbers.filter(function (num) {
  return num % 2 === 0;
});
console.log(evens); // [2, 4]

// reduce
var sum = numbers.reduce(function (total, num) {
  return total + num;
}, 0);
console.log(sum); // 15

// some
var hasEven = numbers.some(function (num) {
  return num % 2 === 0;
});
console.log(hasEven); // true

// every
var allPositive = numbers.every(function (num) {
  return num > 0;
});
console.log(allPositive); // true

// indexOf
console.log(numbers.indexOf(3)); // 2

// lastIndexOf
console.log(numbers.lastIndexOf(3)); // 2

4. JSON Support

Native support for parsing and stringifying JSON data was added.

var jsonString = '{"name":"John", "age":30, "city":"New York"}';
var obj = JSON.parse(jsonString);
console.log(obj.name); // John

var jsonStr = JSON.stringify(obj);
console.log(jsonStr); // {"name":"John","age":30,"city":"New York"}

5. Property Getters and Setters

ES5 introduced the ability to define getters and setters for object properties.

var person = {
  firstName: "John",
  lastName: "Doe",
  get fullName() {
    return this.firstName + " " + this.lastName;
  },
  set fullName(name) {
    var parts = name.split(" ");
    this.firstName = parts[0];
    this.lastName = parts[1];
  },
};

console.log(person.fullName); // John Doe
person.fullName = "Jane Smith";
console.log(person.firstName); // Jane
console.log(person.lastName); // Smith

ES6 features

ECMAScript 6 (ES6), also known as ECMAScript 2015, was officially released in June 2015. This version introduced several significant features and improvements to the JavaScript language. Here are some of the key features introduced in ES6, along with example code snippets for each:

1. Let and Const

Let:

let x = 10;
if (true) {
  let x = 20;
  console.log(x); // 20
}
console.log(x); // 10

Const:

const y = 30;
// y = 40; // This will cause an error because y is constant
console.log(y); // 30

2. Arrow Functions

const add = (a, b) => a + b;
console.log(add(5, 3)); // 8

3. Template Literals

const name = "John";
const message = `Hello, ${name}!`;
console.log(message); // Hello, John!

4. Default Parameters

function greet(name = "stranger") {
  return `Hello, ${name}!`;
}
console.log(greet()); // Hello, stranger!
console.log(greet("Alice")); // Hello, Alice!

5. Destructuring Assignment

Array Destructuring:

const [a, b, c] = [1, 2, 3];
console.log(a, b, c); // 1 2 3

Object Destructuring:

const person = { name: "Bob", age: 25 };
const { name, age } = person;
console.log(name, age); // Bob 25

6. Rest and Spread Operators

Rest Operator:

function sum(...numbers) {
  return numbers.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3, 4)); // 10

Spread Operator:

const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];
console.log(arr2); // [1, 2, 3, 4, 5]

7. Enhanced Object Literals

const name = "Alice";
const age = 30;
const person = {
  name,
  age,
  greet() {
    return `Hello, ${this.name}!`;
  },
};
console.log(person.greet()); // Hello, Alice!

8. Classes

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}

class Dog extends Animal {
  speak() {
    console.log(`${this.name} barks.`);
  }
}

const d = new Dog("Rex");
d.speak(); // Rex barks.

9. Promises

const promise = new Promise((resolve, reject) => {
  setTimeout(() => resolve("Success!"), 1000);
});

promise
  .then((result) => {
    console.log(result); // Success! (after 1 second)
  })
  .catch((error) => {
    console.error(error);
  });

10. Modules

Exporting a module (in file math.js):

export function add(a, b) {
  return a + b;
}

export const pi = 3.14159;

Importing a module (in another file):

import { add, pi } from "./math.js";
console.log(add(2, 3)); // 5
console.log(pi); // 3.14159

ES7 features

ECMAScript 7 (also known as ES7 or ECMAScript 2016) introduced two main features: Array.prototype.includes and the exponentiation operator (**). Below are explanations and code snippets for both features.

1. Array.prototype.includes

The includes method allows you to check if an array contains a certain value, returning true or false as appropriate. This is a more readable and convenient alternative to using indexOf.

Example

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

console.log(numbers.includes(3)); // true
console.log(numbers.includes(6)); // false

const fruits = ["apple", "banana", "mango"];

console.log(fruits.includes("banana")); // true
console.log(fruits.includes("grape")); // false

2. Exponentiation Operator (**)

The exponentiation operator (**) is a shorthand for the Math.pow function, making it easier to write and read exponentiation expressions.

Example

// Using the exponentiation operator
console.log(2 ** 3); // 8
console.log(5 ** 2); // 25

// Equivalent using Math.pow
console.log(Math.pow(2, 3)); // 8
console.log(Math.pow(5, 2)); // 25

// More complex examples
console.log(3 ** 3); // 27
console.log(10 ** -1); // 0.1

Combining Both Features

You can combine both features in a single piece of code for practical purposes, such as checking if an array contains the result of an exponentiation operation.

Example

const baseNumbers = [1, 2, 3, 4, 5];
const exponent = 3;

const results = baseNumbers.map((num) => num ** exponent); // [1, 8, 27, 64, 125]

console.log(results.includes(27)); // true
console.log(results.includes(100)); // false

These features enhance JavaScript by providing more intuitive and concise methods for common tasks.


ES8 features

ECMAScript 8 (also known as ES8 or ECMAScript 2017) introduced four main features:

  1. String Padding

    • padStart
    • padEnd
  2. Object.entries() and Object.values()

  3. Async Functions (Async/Await)

  4. Shared Memory and Atomics

1. String Padding (padStart and padEnd)

These methods allow padding of strings to ensure they reach a certain length.

Example
const str = "5";

console.log(str.padStart(3, "0")); // "005"
console.log(str.padEnd(3, "0")); // "500"

2. Object.entries() and Object.values()

These methods return an array of a given object’s own enumerable string-keyed property [key, value] pairs and values, respectively.

Example
const obj = { a: 1, b: 2, c: 3 };

console.log(Object.entries(obj)); // [ ['a', 1], ['b', 2], ['c', 3] ]
console.log(Object.values(obj)); // [ 1, 2, 3 ]

3. Async Functions (Async/Await)

Async functions allow writing asynchronous code that looks and behaves like synchronous code, greatly simplifying the use of promises.

Example
async function fetchData() {
  try {
    let response = await fetch("https://api.example.com/data");
    let data = await response.json();
    console.log(data);
  } catch (error) {
    console.error("Error fetching data:", error);
  }
}

fetchData();

4. Shared Memory and Atomics

These features enable low-level concurrency primitives in JavaScript, allowing shared memory and atomic operations on shared memory.

Example
// Creating a SharedArrayBuffer
const sharedBuffer = new SharedArrayBuffer(1024); // 1KB buffer
const uint8Array = new Uint8Array(sharedBuffer);

// Using Atomics for thread-safe operations
Atomics.add(uint8Array, 0, 10); // Atomically add 10 to the first element
console.log(Atomics.load(uint8Array, 0)); // 10