Topic 005: ES5, ES6, ES7, ES8 features in JS
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:
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();
New methods for creating, defining properties, and manipulating objects were added.
Object.create()
Object.defineProperty()
Object.defineProperties()
Object.keys()
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"]
Several useful array methods were added in ES5.
Array.isArray()
Array.prototype.forEach()
Array.prototype.map()
Array.prototype.filter()
Array.prototype.reduce()
Array.prototype.some()
Array.prototype.every()
Array.prototype.indexOf()
Array.prototype.lastIndexOf()
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
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"}
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
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:
let x = 10;
if (true) {
let x = 20;
console.log(x); // 20
}
console.log(x); // 10
const y = 30;
// y = 40; // This will cause an error because y is constant
console.log(y); // 30
const add = (a, b) => a + b;
console.log(add(5, 3)); // 8
const name = "John";
const message = `Hello, ${name}!`;
console.log(message); // Hello, John!
function greet(name = "stranger") {
return `Hello, ${name}!`;
}
console.log(greet()); // Hello, stranger!
console.log(greet("Alice")); // Hello, Alice!
const [a, b, c] = [1, 2, 3];
console.log(a, b, c); // 1 2 3
const person = { name: "Bob", age: 25 };
const { name, age } = person;
console.log(name, age); // Bob 25
function sum(...numbers) {
return numbers.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];
console.log(arr2); // [1, 2, 3, 4, 5]
const name = "Alice";
const age = 30;
const person = {
name,
age,
greet() {
return `Hello, ${this.name}!`;
},
};
console.log(person.greet()); // Hello, Alice!
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.
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);
});
math.js
):export function add(a, b) {
return a + b;
}
export const pi = 3.14159;
import { add, pi } from "./math.js";
console.log(add(2, 3)); // 5
console.log(pi); // 3.14159
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.
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
.
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
**
)The exponentiation operator (**
) is a shorthand for the Math.pow
function, making it easier to write and read exponentiation expressions.
// 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
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.
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
ECMAScript 8 (also known as ES8 or ECMAScript 2017) introduced four main features:
String Padding
padStart
padEnd
Object.entries() and Object.values()
Async Functions (Async/Await)
Shared Memory and Atomics
padStart
and padEnd
)These methods allow padding of strings to ensure they reach a certain length.
const str = "5";
console.log(str.padStart(3, "0")); // "005"
console.log(str.padEnd(3, "0")); // "500"
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.
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 ]
Async functions allow writing asynchronous code that looks and behaves like synchronous code, greatly simplifying the use of promises.
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();
These features enable low-level concurrency primitives in JavaScript, allowing shared memory and atomic operations on shared memory.
// 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