JavaScript features in 2021

Mar 17, 2021javascriptjs-concepts

At the time of writing, following new JavaScript proposal features has made to stage-4 and will almost certainly be included in ES2021. You can already start using in latest versions of browsers, Node.js, and Babel.

Note: ECMAScript is the standard upon which JavaScript is based, managed by TC39 committee. ECMAScript was always an unwanted name that makes everything confusing to beginners. People often talk about JavaScript features but refer to ECMAScript specification.

Numeric Separators

Enable underscores (_, U+005F) as separators in numeric literals to improve readability and and have no runtime semantics. It works for numeric literals (integer, bigint, floating-point), fractional, and exponent parts.

1_000_000_000 // decimal literals
0b1010_0001 // binary literals
101_475_938.38 // floating-point literals
0.000_001 // in fractional part
1e10_000 // in exponent part

More info: TC39 proposal, V8

Logical Assignment

Support logical assignment with the new operators &&=, ||=, and ??=. Unlike their mathematical and bitwise counterparts, logical assignments follow the short-circuiting behavior of their respective logical operations. They only perform an assignment if the logical operation would evaluate the right-hand side.

// falsy: false, 0, -0, 0n, "", null, undefined, and NaN
// truthy: all values are truthy unless defined as falsy
// nullish: null or undefined

a ||= b
// Logical OR assignment
// Equivalent to: a || (a = b);
// Only assigns if a is falsy

a &&= b
// Logical AND assignment
// Equivalent to: a && (a = b);
// Only assigns if a is truthy

a ??= b
// Logical nullish assignment
// Equivalent to: a ?? (a = b);
// Only assigns if a is nullish

More info: TC39 proposal, V8, MDN

Weak References

This feature contains two advanced objects WeakRef and FinalizationRegistry. These interfaces can be used independently or together, depending on the use case. Their correct use takes careful thought, and they are best avoided if possible.

A WeakRef is an object that is used to refer to a target object without preserving it from garbage collection. WeakRefs can dereference to allow access to the target object, if the target object hasn’t been reclaimed by garbage collection.

// Create a WeakRef object referring to a given target object
const ref = new WeakRef(targetObject)

// Return the WeakRef instance's target object, or undefined if the target object has been garbage-collected
const obj = ref.deref()

A FinalizationRegistry object lets you request a callback when an object is garbage-collected.

// Create a registry object that uses the given callback
const registry = new FinalizationRegistry([callback])

// Register an object with a registry instance so that if the object is garbage-collected, the registry's callback may get called
registry.register(target, heldValue, [unregisterToken])

// Unregister a target object from a registry instance
registry.unregister(unregisterToken)

More info: TC39 proposal, V8

Promise.any()

Promise.any() accepts an iterable of promises and returns a promise that is fulfilled by the first given promise to be fulfilled, or rejected with an AggregateError holding the rejection reasons if all of the given promises are rejected.

This method is useful for returning the first promise that fulfills. It short-circuits after a promise fulfills, so it does not wait for the other promises to complete once it finds one.

Promise.any(promises).then(
  (first) => {
    // Any of the promises was fulfilled.
  },
  (error) => {
    // All of the promises were rejected.
    // error instanceof AggregateError
  }
)

More info: TC39 proposal, V8, MDN

String.prototype.replaceAll()

Currently there is no way to replace all instances of a substring in a string without use of a global regexp. String.prototype.replace only affects the first occurrence when used with a string argument.

String.prototype.replaceAll() would give developers a straight-forward way to accomplish this common, basic operation.

'aabbcc'.replaceAll('b', '.') // 'aa..cc'
'aabbcc'.replaceAll(/b/g, '.') // 'aa..cc'

More info: TC39 proposal, MDN, V8

Summary

Here are some new features that you can expect to be released in 2021, they are the proposals that made it to stage-4 and that will almost certainly be included, already implemented in latest browsers and babel.