DEV Community

loading...
Cover image for Upcoming JavaScript Features in 2021

Upcoming JavaScript Features in 2021

ageekdev profile image πŸ…°οΈ GEEK Originally published at ageek.dev ・4 min read

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 refering 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
Enter fullscreen mode Exit fullscreen mode

More info: TC39 proposal, ageek, 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
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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
  }
)
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

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.

Discussion (14)

pic
Editor guide
Collapse
michaelcurrin profile image
Michael • Edited

I'm glad to have that replaceAll. I've been annoyed at having to add a g to regex replacement.

What is a case for when you want to use .any? Normally I like .all to wait for all promises like scrapes web pages. I don't know when I'd want the first to return and throw away the others.

For comparison, Ruby has had ||= for a long time and Python has a weak references ability weakref, as well as the underscore numbers.

Collapse
ageekdev profile image
πŸ…°οΈ GEEK Author

Promise.any most likely for trying to achieve one result with different cost/speed to increase availability like downloading identical file from multiple servers or scraping latest scores from several scoreboards.

Collapse
michaelcurrin profile image
Michael

Yes if there is different performance for each. Though with tradeoff that querying all 5 sources at the same will mean even the fastest source is going to take longer than if you queried it alone. Unless the network and device is able to handle loading them in parallel? I don't know so much at the level.

Thread Thread
ageekdev profile image
πŸ…°οΈ GEEK Author

One example is you can just promise.any several preconditons, pick the first satisfied one and run heavy operation on that only.

Collapse
thecerealcoder profile image
Chris

Sweet, I’ll be using those new logical assignment operators and replaceAll method for sure

Collapse
pris_stratton profile image
pris stratton

Promise.any sounds similar to Promise.race, which I admit I’ve never used.

Collapse
ageekdev profile image
πŸ…°οΈ GEEK Author

Promise.all is something we use more often. Check out this excellent post v8.dev/features/promise-combinators for all promise combinators.

Collapse
pris_stratton profile image
pris stratton

That’s a nice resource. I have used Promise.all when reading from several
JSON files before.

Collapse
tastefulelk profile image
Sebastian Bille

Definitely looking forward to the new logical assignment operators! πŸŽ‰

Collapse
ageekdev profile image
πŸ…°οΈ GEEK Author

Most short-circuiting operators seem very neat to use but actually a source of many bugs and surprises πŸ€“. I still prefer explicit if-else and early returns when possible.

Collapse
tastefulelk profile image
Sebastian Bille

Definitely agree about early returns, they can often reduce the complexity a lot on their own. But shortcuts like these can still be neat sometimes imo πŸ™ƒ

Collapse
andreespirela profile image
andreespirela • Edited

They're not "upcoming" anymore, they have already landed in V8.

Collapse
ageekdev profile image
πŸ…°οΈ GEEK Author

Sure most of them implemented months ago in 2020, check tc39.es/process-document/, need approval of new standard by the ECMA General Assembly in July.

Collapse
harshrathod50 profile image
Harsh Rathod

The heading should be "Upcoming JavaScript features in 2021 to turn the current JS ecosystem into chaos and further increase support issues".