Standard ECMA-262

  • Specification that defines how ECMAScript works
  • First version released in 1997
  • ES3 in 1999
  • ES5 in 2009
  • ES6 in 2015 (ES2015)
  • Now a new version is released every year
  • Can be found in Github

The 5 stages

Stage Purpose Criteria Implementation
0 Strawman Allow input None N/A
1 Proposal Describe the what, why and how
  • Describe the problem it solves
  • Illustrative usage examples and high level API
Polyfills / demos
2 Draft Precise syntax and semantics
  • Initial draft of the formal specification
Experimental
3 Candidate Gather feedback from implementations and users
  • Spec text should be finished
Spec compliant
4 Finished Ready for inclusion to ECMA-262
  • Has Test 262 acceptance tests
  • Two compatible implementations which pass tests
Shipping

Object rest/spread properties

// Rest
const obj = { foo: 1, bar: 2, baz: 3 };
const { foo, ...rest } = obj;
// foo is 1
// rest is { bar: 2, baz: 3 }

// Spread
const obj = { foo: 1, bar: 2, baz: 3 };
const other = { ...obj, qux: 4 };
// other is { foo: 1, bar: 2, baz: 3, qux: 4 }

Promise.prototype.finally

promise
  .then(result => {···})
  .catch(error => {···})
  .finally(() => {···});

Named regex captures

const fsPath = "/root/path/to/the/Resource";
const regexp = /\/
  (?<hierarchy>[^\/]+)
  (?<membership>\/.*?)[\/]*
  (?<name>[^\/]*)
  $/u;

const { groups } = regexp.exec(fsPath)
// {
//   hierarchy:  "root",
//   membership: "/path/to/the",
//   name:       "Resource",
// }

Other regex feature

Optional catch binding

let isTheFeatureImplemented = false;
try {
  // Check if it is
  isTheFeatureImplemented = true;
} catch { }

JSON superset

  • U+2028 LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR
  • JSON can contain them
  • JS strings cannot

Dynamic import()

const main = document.querySelector("main");
const dynamicModule = "myfile";

import(`./dynamic/${ dynamicModule }.js`)
  .then(module => {
    module.loadPageInto(main);
  })
  .catch(err => {
    main.textContent = err.message;
  });

globalThis

  • On browsers window, this, self
  • On Node.js global or this
  • Can't use name global

New Class features

class Counter {
  // Public, private and static fields
  publicValue = 0;
  #privateValue = 0;
  static staticField = 0;

  // Private getters and setter
  get #value() { return #privateValue; }
  set #value(val) {
    this.#privateValue = val;
  }

  constructor() {}

  // Private methods
  #increment() {
    this.#privateValue++;
  }
}

BigInt: Arbitrary precision integers

JS only supports integers up to 253-1

// Literal + constructor
const theBiggestInt = 9007199254740991n;
const alsoHuge = BigInt(9007199254740991);
const hugeButString = BigInt('9007199254740991');
// ↪ 9007199254740991n

// Same operators as with Number
const bigN = 2n ** 54n;
// ↪ 18014398509481984n

Array.prototype.{flatMap,flat}

// Array.prototype.flat( [ depth ] )
const nestedArr = [[1], [2, 3], [4]]
nestedArr.flat()
// > [1, 2, 3, 4]

// Array.prototype.flatMap( mapperFunction [ , thisArg ] )
const nestedArr = [[1], [2, 3], [4]]
nestedArr.flatMap(x => x + 1)
// > [2, 3, 4, 5]

Object.fromEntries

Reverse of Object.entries
obj = Object.fromEntries([
  ['a', 0],
  ['b', 1]
]);

// obj is { a: 0, b: 1 }

Decorators

@defineElement("num-counter")
class Counter extends HTMLElement {
  @observed #x = 0;

  @bound
  #clicked() {
    this.#x++;
  }

  @bound
  render() {
    this.textContent = this.#x.toString();
  }
}

Temporal

A modern immutable date time API

Object Name Description Example
CivilDate Date 2017-12-31
CivilTime Time of day 17:00:00
CivilDateTime Date and time 2017-12-31T12:00:00
Instant Point in timeline w/o time zone 2017-12-31T00:00:00Z
ZonedInstant Point in timeline with time zone 2017‑12‑31T09:00:00+09:00[Asia/Tokyo]
Proposal Stage 1 Stage 2 Stage 3 Stage 4 Time (months)
Object Rest spread 2014-09 2015-07 2016-09 2018-01 40
Async iterators 2016-01 2016-03 2016-09 2018-01 24
RegEx Unicode escape 2016-07 2016-09 2017-03 2018-01 18
Promise.finally 2016-07 2016-07 2017-07 2018-01 18
JSON superset 2017-09 2017-11 2018-01 2018-05 8
Private methods & accessor ??? 2017-07 2017-09
Public Class fields ??? 2016-07 2017-07
String.prototype.matchAll 2015-09 2017-09 2018-01
String.prototype.{trimLeft,trimgRight} 2015-07 2016-07 2018-01
System.global ??? 2016-03 2016-09
dynamic import() 2016-09 2016-09 2016-12
Temporal 2017-03 2018-09
String.prototype.replaceAll 2017-11
do expression 2017-01

New features on different levels

  • New (standard library) functions
  • New primitives & objects
  • New syntax
  • New operators

Features for different paradigms

  • Object-oriented features
  • Functional features
  • Reactive features

Era of transpilers

Babel and TypeScript allow new features even before full browser support

Enables faster feedback loop between web developers and implementors

Check the latest support from the ECMAScript compatibility table

Conclusion

Lots of interesting proposals

JS is becoming ever more multi-paradigm

Transpilers allow early usage of features