All about ECMAScript.
All about ECMAScript.
ECMAScript (ES) and JavaScript are often used interchangeably, but there is a
distinction between the two.
JavaScript:
JavaScript is a programming language that was originally developed by Brendan
Eich at Netscape in the mid-1990s. It was created to add interactivity to web pages
and has since become the de facto scripting language for web development.
JavaScript is widely supported by web browsers and is used on both the client-side
(browser) and server-side (Node.js) for building web applications.
ECMAScript:
ECMAScript is a standardized specification that defines the syntax, semantics, and
behavior of scripting languages. It is maintained by Ecma International, a standards
organization. JavaScript is the most well-known and widely used implementation of
the ECMAScript specification. The ECMAScript specification is regularly updated,
with new versions released periodically, introducing new features, syntax
enhancements, and improvements to the language.
For example, ECMAScript 6 (ES6) introduced many new features to JavaScript, such
as arrow functions, classes, modules, and enhanced object literals. These features
were standardized in the ECMAScript specification, and JavaScript engines and
environments implemented them accordingly.
While ES7 (ECMAScript 2016) did not introduce major syntax changes or
groundbreaking features, it did include a few smaller additions and improvements.
Here are a couple of notable additions in ES7:
1. Array.prototype.includes():
The includes() method was introduced to the Array prototype.
It allows you to check if an array includes a specific element, returning true
or false.
The method simplifies the process of checking array membership compared
to using indexOf().
Example:
const arr = [1, 2, 3];
console.log(arr.includes(2)); // Output: true
console.log(arr.includes(4)); // Output: false
Example:
console.log(2 ** 3); // Output: 8 (2 raised to the power of 3)
ES8 (ECMAScript 2017)
1. String padding:
The padStart() and padEnd() methods were added to the String prototype.
They allow you to pad a string with a specified character to achieve a desired
length.
Example:
const str = 'Hello';
console.log(str.padStart(8, '*')); // Output: "***Hello"
console.log(str.padEnd(8, '-')); // Output: "Hello---"
2. Object.values():
The Object.values() method returns an array of the enumerable property
values of an object.
Example:
const obj = { a: 1, b: 2, c: 3 };
const values = Object.values(obj);
console.log(values); // Output: [1, 2, 3]
3. Object.entries():
The Object.entries() method returns an array of key-value pairs (as arrays)
for the enumerable properties of an object.
Example:
const obj = { a: 1, b: 2, c: 3 };
const entries = Object.entries(obj);
console.log(entries); // Output: [["a", 1], ["b", 2], ["c", 3]]
4. Trailing commas in function parameter lists and calls:
ES8 allows trailing commas in function parameter lists and function calls,
which makes it easier to add or remove parameters without modifying other
parts of the code.
Example:
function myFunction(a, b, c,) {
// Function code
}
myFunction(1, 2, 3,); // Trailing comma is allowed
5. Async functions:
ES8 introduced async functions, which make working with asynchronous
code using promises more straightforward.
async functions allow the use of the await keyword to pause the execution
until a promise is resolved or rejected.
Example:
async function fetchData() {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
return data;
}
ES9 (ECMAScript 2018)
1. Asynchronous Iteration:
ES9 introduced the for-await-of loop, which allows for asynchronous
iteration over asynchronous data sources such as Promises, Async Iterators,
and other async-enabled constructs.
Example:
async function fetchData() {
const data = await getData();
for await (const item of data) {
// Handle each item asynchronously
}
}
2. Rest/Spread Properties:
ES9 extended the rest and spread syntax for objects, allowing the use of ...
to spread properties in object literals and also in object destructuring
assignments.
Example:
const { a, b, ...rest } = { a: 1, b: 2, c: 3, d: 4 };
console.log(a); // Output: 1
console.log(b); // Output: 2
console.log(rest); // Output: { c: 3, d: 4 }
3. Promise.prototype.finally():
The finally() method was added to the Promise prototype, allowing you to
specify a callback that will be executed regardless of whether the promise is
fulfilled or rejected.
Example:
fetch('https://api.example.com/data')
.then(response => {
// Process the response
})
.catch(error => {
// Handle errors
})
.finally(() => {
// Cleanup or final actions
});
Example:
const regex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = regex.exec('2022-01-15');
console.log(match.groups.year); // Output: 2022
console.log(match.groups.month); // Output: 01
console.log(match.groups.day); // Output: 15
ES10 (ECMAScript 2019):
Example:
try {
// Code that may throw an error
} catch {
// Handle the error without assigning it to a variable
}
Example:
const nestedArray = [1, [2, [3, [4]]]];
console.log(nestedArray.flat(2)); // Output: [1, 2, 3, 4]
const array = [1, 2, 3];
console.log(array.flatMap(x => [x, x * 2])); // Output: [1, 2, 2, 4, 3, 6]
Example:
const text = ' Hello, World! ';
console.log(text.trimStart()); // Output: 'Hello, World! '
console.log(text.trimEnd()); // Output: ' Hello, World!'
4. Object.fromEntries():
The Object.fromEntries() method transforms a list of key-value pairs (2D
array) into an object.
Example:
const entries = [['a', 1], ['b', 2], ['c', 3]];
const obj = Object.fromEntries(entries);
console.log(obj); // Output: { a: 1, b: 2, c: 3 }
5. BigInt:
ES10 introduced the BigInt data type, which allows you to represent
arbitrarily large integers.
It provides more precise numeric values than the Number type.
Example:
const bigNumber = BigInt('9007199254740991');
console.log(bigNumber); // Output: 9007199254740991n
ES11 (ECMAScript 2020):
Example:
const obj = {
property1: {
property2: {
value: 42
}
}
};
console.log(obj.property1?.property2?.value); // Output: 42
console.log(obj.property1?.property3?.value); // Output: undefined
Example:
const value1 = null;
const value2 = undefined;
const defaultValue = 42;
console.log(value1 ?? defaultValue); // Output: 42
console.log(value2 ?? defaultValue); // Output: 42
3. Dynamic Import:
ES11 introduced dynamic import, which allows you to import modules
dynamically at runtime using a function-like syntax.
It returns a promise that resolves to the module.
Example:
const module = import('./myModule.js');
module.then((m) => {
// Use the imported module
});
4. BigInt:
The BigInt type, introduced in ES10, was enhanced in ES11 to support
additional operations like BigInt.prototype.toLocaleString() and
BigInt.prototype.toJSON().
5. Promise.allSettled():
The Promise.allSettled() method returns a promise that resolves after all
the provided promises have settled, i.e., either fulfilled or rejected.
It returns an array of objects representing the fulfillment or rejection status
of each promise.
Example:
const promises = [
Promise.resolve('Success'),
Promise.reject('Error'),
Promise.resolve('Another Success')
];
Promise.allSettled(promises)
.then((results) => {
console.log(results);
});
ES12 (ECMAScript 2021):
1. String.prototype.replaceAll():
The replaceAll() method was added to the String prototype, allowing you to
replace all occurrences of a substring with a new substring.
It returns a new string with all occurrences replaced.
Example:
const str = 'Hello, hello, hello!';
const newStr = str.replaceAll('hello', 'hi');
console.log(newStr); // Output: 'Hi, hi, hi!'
2. Numeric Separator:
ES12 introduced the ability to use underscores (_) as numeric separators
within numeric literals.
This feature allows you to improve the readability of large numbers by
separating them into more manageable parts.
Example:
const billion = 1_000_000_000;
const pi = 3.14_15_92;
console.log(billion); // Output: 1000000000
console.log(pi); // Output: 3.141592
3. Promise.any():
The Promise.any() method takes an iterable of promises and returns a
promise that fulfills as soon as one of the promises in the iterable fulfills.
It returns the value of the first fulfilled promise.
Example:
const promises = [
Promise.reject('Error 1'),
Promise.resolve('Success 1'),
Promise.reject('Error 2'),
Promise.resolve('Success 2')
];
Promise.any(promises)
.then((value) => {
console.log(value);
})
.catch((error) => {
console.log(error);
});
Example:
let x = null;
let y = 5;
x ||= 10; // x is assigned 10 because it is bullish.
y &&= 2; // y is assigned 2 because it is truth.
console.log(x); // Output: 10
console.log(y); // Output: 2