ES2021/22 and Beyond, Whats (es.)Next?

Some examples and excerpts of the latest ECMA specifications.

by Gion Kunz

Gion Kunz

  • Angular GDE since 2018
  • Front-end developer, web standards advocate
  • Specialized in spa development using Angular
  • Onsite ramp-ups, coaching and implementation support in projects
  • Author of the book "Mastering Angular Components"
  • Frequent speaker at conferences and meetups
  • Teacher for web development and UX engineering at the SAE Institute in Zurich
  • Tutor at O'Reilly Safari Online Training
  • Contributor on the Angular project, author of Chartist.js library

Founder, UI Developer, UX Enthusiast at syncrea GmbH

If I am not in the Web universe, I  to observe the real one.

M31 Andromeda Galaxy, ~2.5 million light-years from Earth and the nearest large galaxy to the Milky Way

  • ECMAScript 2022

    • Class field declarations

    • Private methods and fields

    • Static public methods and fields

    • .at() for Indexed Collections

  • ECMAScript 2020

    • BigInt

    • Dynamic Imports

    • Nullish Coalescing

    • Optional Chaining

    • String#matchAll

  • ECMAScript 2021

    • String#replaceAll 🥳

    • WeakRef

Overview

ECMA / TC39 Process

  • TC39 is a diverse group of members working with JavaScript under ECMA International
  • TC39 collaborates with the community to maintain and evolve the ECMAScript specification
  • The TC39 process allows making changes in the ECMAScript specification using five regulated stages
  • TC39 must approve each stage of the TC39 process for any change in the specification
  • New editions of the specification are delivered every year
  • Stage 0 represents an initial idea for addition or change to the specification
  • Stage 1 is a formal proposal describing a problem and suggesting a proper solution
  • Stage 2 is an initial draft of the proposal specification
  • Stage 3 represents the draft when it’s almost final but ready for last feedback
  • Stage 4 is when the proposal specification completely ready and included within the next edition

ECMAScript 2020

BigInt

const aBigInteger = 98765432123456789n;
const alsoAbigInteger = BigInt('98765432123456789');
console.log(typeof aBigInteger) // bigint

DynamicImports

async function getXfromModule() {
  const m = await import('./module.js');
  return m.x;
}

getXfromModule().then(console.log);

Nullish Coalescing

const nullValue = null;
const emptyText = ''; // falsy
const someNumber = 42;

const valA = nullValue ?? 'default for A';
const valB = emptyText ?? 'default for B';
const valC = someNumber ?? 0;

console.log(valA); // 'default for A'
console.log(valB); // ''
console.log(valC); // 42

Optional Chaining

const adventurer = {
  name: 'Alice',
  cat: { name: 'Dinah' }
};

const dogName = adventurer.dog?.name;
console.log(dogName);
// expected output: undefined

console.log(adventurer.someNonExistentMethod?.());
// expected output: undefined

String#matchAll

const regexp = /foo[a-z]*/g;
const str = 'table football, foosball';
let match;

while ((match = regexp.exec(str)) !== null) {
  console.log(`Found ${match[0]} @ ${match.index}`);
}

Before matchAll

String#matchAll

const regexp = /foo[a-z]*/g;
const str = 'table football, foosball';

for (const match of str.matchAll(regexp)) {
  console.log(`Found ${match[0]} @ ${match.index}`);
}

After matchAll

ECMAScript 2021

String#replaceAll 🥳

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(find, 'g'), replace);
}

console.log(replaceAll('oOoOoOoOoOo', 'O', '.'));

Before replaceAll

String#replaceAll 🥳

console.log('oOoOoOoOoOo'.replaceAll('O', '.'));

After replaceAll

WeakRef

export function cached(getFresh = () => null) {
  let ref;
  return () => {
    if (!ref || !ref.deref()) {
      ref = new WeakRef(getFresh());
    }
    return ref.deref();
  };
}

const cachedData = cached(() => Array(1000).fill(1));
console.log(cachedData());
console.log(cachedData() === cachedData());

ECMAScript 2022

Class field declarations

export class Fruit {
  name;
  sweet = true;
  color;
}

const banana = new Fruit();
console.log(banana);
// Fruit {sweet: true}

Private and static methods and fields

export class Singleton {
  static #instance;

  constructor() {
    return Singleton.#instance ??= this;
  }

  static instance() {
    return new Singleton();
  }
}

const s1 = new Singleton();
const s2 = new Singleton();
const s3 = Singleton.instance();
console.log([s1, s2, s3].every(s => s === s1)); // true

.at() for Indexed Collections

// Before
const names = ['Joe', 'Doe', 'Moe'];
console.log(names[names.length - 1]);
// Or
console.log([...names].pop());

// After
console.log(names.at(-1));

Let's create together.

Thanks!