DEV Community

Cover image for JavaScript: Latest Stage-4 features

Posted on

JavaScript: Latest Stage-4 features

The below features advanced to stage-4 in the recent TC39 meeting:

  • Intl.DateTimeFormat: dateStyle & timeStyle
  • Intl.ListFormat.
  • Logical Assignment.
  • Numeric Separators.
  • Promise.any & AggregateError.
  • WeakRefs & FinalizationRegistry.

Let us see quick code example for the same:


This proposal adds two options to Intl.DateTimeFormat: dateStyle and timeStyle

let date = new Intl.DateTimeFormat("en" , {
  timeStyle: "medium",
  dateStyle: "short"

date.format(; // "01.02.2020, 13:30"

// styles: undefined, "full", "long", "medium", or "short"
Enter fullscreen mode Exit fullscreen mode


This proposal enable language-sensitive list formatting

const lf = new Intl.ListFormat("en", {
    localeMatcher: "best fit", // can be "lookup"
    type: "conjunction", // "conjunction", "disjunction" or "unit"
    style: "long", // other values: "short" or "narrow"

lf.format(['Apple', 'Orange' , 'Plum']);
// > "Apple, Orange, and Plum"

  localeMatcher -> "best fit" or "lookup"
  type -> "conjunction", "disjunction" or "unit"
  style -> "long", "short" or "narrow"
Enter fullscreen mode Exit fullscreen mode

Logical Assignment

This proposal allows to combine Logical Operators and Assignment Expressions.

// "Or Or Equals" (or, the Mallet operator :wink:)
a ||= b;
a || (a = b);

// "And And Equals"
a &&= b;
a && (a = b);

// "QQ Equals"
a ??= b;
a ?? (a = b);
Enter fullscreen mode Exit fullscreen mode

Numeric Separators.

This proposal is a merge between proposal-numeric-underscores, to extend the existing NumericLiteral to allow a separator character between digits.

1_000_000_000           // Billion
101_475_938.38          // Hundreds of millions

let fee = 123_00;       // $123 

let hex = 0xA0_B0_C0;

let octal = 0o1234_5670;

Enter fullscreen mode Exit fullscreen mode

Promise.any & AggregateError.

This proposal of 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

try {
  const first = await Promise.any(promises);
  // Any of the promises was fulfilled.
} catch (error) {
  // All of the promises were rejected.
Enter fullscreen mode Exit fullscreen mode
const aggregateError = new AggregateError([errA, errB, errC], 'Oops!');
Enter fullscreen mode Exit fullscreen mode

WeakRefs & FinalizationRegistry.

This proposal allows creating weak references to objects with the WeakRef and running user-defined finalizers after objects are garbage-collected, with the FinalizationRegistry class

const makeWeakCached = f => {
  const cache = new Map();
  const cleanup = new FinalizationRegistry(key => {
    const ref = cache.get(key);
    if (ref && !ref.deref()) cache.delete(key);

  return key => {
    const ref = cache.get(key);
    if (ref) {
      const cached = ref.deref();
      // See note below on concurrency considerations.
      if (cached !== undefined) return cached;

    const fresh = f(key);
    cache.set(key, new WeakRef(fresh));
    cleanup.register(fresh, key);
    return fresh;

const getImageCached = makeWeakCached(getImage);
Enter fullscreen mode Exit fullscreen mode

Hope you liked the proposals, feel free to comment with your thoughts! 🤓


Top comments (7)

mjswensen profile image
Matt Swensen

Awesome! The Intl API is becoming so nice—chipping away at the small problems we either spend too much time on or turn to libraries for. The more of that type of stuff we can build into the platform, the better 😌

jcarlosweb profile image
Carlos Campos • Edited

because there is no method called format dates, something like this:

(new Date())->format('d-m-Y'); // 24-07-2020

I don't understand why they make such a mess, when the easy thing is for you to format. I find it INCREDIBLE.

udkl profile image
Uday K • Edited

JS as a language itself is such a mess ! I don’t understand the hipstering around it really. It’s only popular because there is no other option on the browser. And don’t even get me started on nodeJs.

fkereki profile image
Federico Kereki

Are you sure about ||= and the other operators?

I thought that a ||= b actually meant a = (a || b) -- am I wrong?

ojoaofernandes profile image
João Fernandes


Convenience operators, inspired by Ruby's. We already have a dozen mathematical assignment operators, but we don't have ones for the often used logical operators.

function example(a) {
  // Default `a` to "foo"
  if (!a) {
    a = 'foo';

A proposal to combine Logical Operators and Assignment Expressions:

// "Or Or Equals" (or, the Mallet operator :wink:)
a ||= b;
a || (a = b);

jeromecovington profile image
Jerome Covington

Thanks for another awesome post. I'm particularly interested in WeakRef. It seems to me that "hooking" into the garbage collection cycle would otherwise be impossible without bridging into C++.

pentacular profile image

Very nice.

I like the numeric separator option; a problem I hadn't considered. :)