What is ECMA Script 12?
Since publication of the first edition in 1997, ECMAScript has grown to be one of the world's most widely used general-purpose programming languages. It is best known as the language embedded in web browsers but has also been widely adopted for server and embedded applications. You can now write full stack applications in pure JS with NodeJS and JavaScript.
Let's get started taking a look at the useful new features for frontend developers in the latest version of ECMA Script.
The examples shown below can be found in my
String.repalceAll(searchValue, replaceValue)
Ever wanted to replace all your matches at once? The new String method replaceAll() takes a String and searches across the entire length then replaces them all with the replacement value. The search value can be a string literal or a regular expression making this new method a powerful shorthand.
const regex = /title: ([a-zA-Z]+)/g; //match all occurances of 'title: title' pattern
const str = 'title: Doctor Joshua Berkowitz title: Resident Ted Hamilton';
let resultString = str.replaceAll(regex, 'Mr.');
console.log(resultString); // Output => "Mr. Joshua Berkowitz Mr. Ted Hamilton"
Private Class Methods & Props
Sometimes its better to keep things to yourself and other times it's better to let it out. At least that's my pov on life and it may just be one of the new best features of ECMA2021.
Private class methods are not available on new instances of that class and are only able to be referenced within.
Many other programming languages already support the public/private paradigm so seeing it roll into a clear definition within the ECMA standard is super nice.
Let's see what we can do with private class methods and private properties in JavaScript 2021.
// Restrict a class method to only the scope of its parent class. Helps in reducing global pollution. ;)
// Calling a private method from a public method will allow access to the private child
// There is another limitation: you can't declare private fields or methods via object literals.
class Product {
//declare your private variables here then initialize in the class constructor
#id;
#cost;
constructor(){
this.#cost = 5;
this.#id = 13245679; //assign your private variable in the constructor
}
getPrice(){
//You can access the private the private method by calling it as you see it, making locating them more apparent when reading code.
const price = this.#getCost(this.#cost)*5;
console.log(price);
}
//Private method
#getCost(cost){
return Number(cost)
}
getId(){
return this.#id
}
}
const product = new Product(123456);
// Calling the private method from a new instance of the class will result a TypeError since it is not accessible.
product.getPrice(); // Output => 25
product.getCost(); // Output => Uncaught TypeError: product.getCost is not a function because it is private
console.log(product.#id); // Output => Private field '#id' must be declared in an enclosing class
console.log(product.getId()); // Output => 13245679 //Public method accesses private property successfully
Promise.any([...Promise])
The new Promie.any() method takes an iterable of Promise objects and returns a single promise that resolves as soon as ANY of the iterable promises resolve, if all promises are rejected then it returns an AggregateError.
AggregateError is a new Error type in ECMA 2021 and represents a iterable group of Errors
Let's see how it works in the browser
const ant = Promise.reject(0); // The ant can win this race
const hair = new Promise((resolve) => setTimeout(resolve, 50, 'hair')); // The hair finishes the fastest
const tortise = new Promise((resolve) => setTimeout(resolve, 5000, 'turle')); // The turtle takes his time but still loses.
const promises = [ant, hair, tortise];
Promise.any(promises).then((value) => {console.log(`Looks like the ${value} won the race`)});
// Output => "Looks like the hair won the race"
Logical Assignment Operators
It sounds like the drop of a new season of Call of Duty but we've got a new operator this season in ECMA Script 😉 The logical assignment operators append the equals sign '=' to the comparison operator for a quick conditional assignment of your variables.
let firstValue = false;
let otherValue = 'other value';
//If the first value is falsy it returns the other value
firstValue ||= otherValue;
console.log(firstValue); // Output => 'other value'
//If all values are truthy it returns the otherValue else the firstValue
firstValue &&= otherValue;
console.log(firstValue); // Output => false
//If firstValue is null or undefined it returns the otherValue else the firstValue
firstValue ??= otherValue;
console.log(firstValue); // Output => false
Visual Number Separator
Perhaps this isn't the greatest addition to the standard since async await but it does help speed up those long coding sessions and scrolling through code reviews. The underscore in number literals is now a separator placeholder. It introduces a visual separator for developers to easily determine the value of large numbers. The separator also works for binary and hex literals.
Let's see how this works out for numbers.
//Regular number literals
let largeNumber = 9_900_000_000_000;
console.log(typeof largeNumber); // Output => number
console.log(largeNumber); // Output => 9900000000000
WeakRef
The weakRef addition is an object that holds a weak reference to another object without preventing garbage collection. Correct use of WeakRef takes careful thought, and it's best avoided if possible.
FinalizationRegistry
The Finalization Registry is a way to request a callback when an object is garbage collected. Correct use of FinalizationRegistry takes careful thought, and it's best avoided if possible.