JS TutorialLesson #137

ECMAScript 2026

ECMAScript 2026 (ES2026), the 17th edition of the JavaScript language specification, was officially ratified by ECMA International on June 30, 2026.

New Features in JavaScript 2026

ECMAScript 2026 (ES2026), the 17th edition of the JavaScript language specification, was officially ratified by ECMA International on June 30, 2026.

  • Accurate Math with Math.sumPrecise()
  • Error detection with Error.isError()
  • Asynchronous array creation with Array.fromAsync()
  • Map upsert with getOrInsert()
  • High-precision JSON with rawJSON()
  • Base64 and hexadecimal encodings for Uint8Array
Features Pushed to ES2027 > While highly visible in the ecosystem through mature polyfills, a couple of major proposals just missed > the June 2026 cutoff for official inclusion and are officially slated for next year's spec: > Temporal API > The long-time-overdue successor to the buggy, 30-year-old Date object. > Unlike Date, Temporal objects are immutable and provide first-class support for time zones > and non-Gregorian calendars. > Explicit Resource Management (using keyword) > C#-style block-scoped disposal variables that auto-clean up database connections > and streams when leaving context, avoiding try...finally boilerplate.

Accurate Math with Math.sumPrecise()

[Math.sumPrecise()](js_2026.asp?#mark_sumprecise) fixes the classic 0.1 + 0.2 === 0.30000000000000004 floating-point problem when summing lists of numbers.

Computers do not think in base-10 decimals like humans; they think in binary bits, which causes structural math flaws in programming.

The Problem: In JavaScript, 0.1 + 0.2 has historically equaled 0.30000000000000004 due to floating-point rounding errors. This is dangerous for financial apps.

The Fix: Math.sumPrecise changes how the underlying language engine calculates a list of decimals, bypassing the system's structural limitation to deliver a perfect sum.


Map Upsert with getOrInsert()

Map.prototype.getOrInsert removes the boilerplate of checking if a key exists before adding an item to a Map structure.

A data structure (like an Array or a Map) holds your information. Previously, JavaScript's built-in structures lacked common-sense shortcuts found in other languages.

The Problem: If you wanted to update a dictionary (Map), you had to write an if statement to check if the key existed, create it if missing, and then update it.

The Fix: Map.prototype.getOrInsert lets you find or create data in one quick move. It expands what the data structure can do natively.

Example

Example Code

javascript
Try it Yourself
const userRoles = new Map();

// Old Way: Multi-line checks

if (!userRoles.has("admin")) {

  userRoles.set("admin", []);

}

userRoles.get("admin").push("Alice");

// New ES2026 Way: Single-line default insertion

userRoles.getOrInsert("admin", []).push("Bob");

userRoles.getOrInsert("admin", []).push("Charlie");

console.log(userRoles.get("admin")); // ['Bob', 'Charlie']

High-Precision JSON with rawJSON()

JSON.rawJSON preserves large numbers (like ID strings from databases) without losing digits due to internal rounding.

Example

Example Code

javascript
Try it Yourself
const precisionLossJSON = '{"id": 9223372036854775807}';

// New ES2026 Reviver: Accesses the raw source string before rounding

const data = JSON.parse(precisionLossJSON, (key, value, context) => {

  if (key === 'id') {

    return context.source; // "9223372036854775807" as a string

  }

  return value;

});

// New ES2026 Stringify: Outputs the unrounded big integer safely

const output = JSON.stringify({

  id: JSON.rawJSON("9223372036854775807")

});

Error.isError()

Error.isError() is a static method to reliably check if a value is an Error object, improving error handling and debugging.

Error.isError() reliably detects error objects even if they originated from inside an or a separate runtime sandbox.

Example

Example Code

javascript
Try it Yourself
Error.isError(new TypeError());   // true

Error.isError({ name: "Error" }); // false

Realm-safe error check: An Error from an iframe verifies with Error.isError() and fails with instanceof.

Example

Example Code

javascript
Try it Yourself
try {

  throw new TypeError("Invalid format");

} catch (err) {

  // Old Way: Could fail across different window contexts

  console.log(err instanceof Error);

  // New ES2026 Way: Globally reliable

  console.log(Error.isError(err)); // true

}

Browser Support

Error.isError() is already supported in many browsers:

Chrome 134Edge 134Firefox 138Safari ❌Opera 119
Mar 2025Mar 2025Apr 2025❌May 2025

Array.fromAsync()

[Array.fromAsync()](js_2026.asp?#mark_fromasync) is a feature that allows developers to create a new Array instance from asynchronous iterables, array-like objects, or Promises, streamlining the handling of data from async sources.

Example

Example Code

javascript
Try it Yourself
// An async generator simulating a paginated API

async function* fetchPages() {

  yield;

  yield;

}

// New ES2026 Way: Resolves and flattens natively

const allData = await Array.fromAsync(fetchPages(), flatMap => flatMap);

console.log(allData); // [1, 2, 3, 4]

Example

Example Code

javascript
Try it Yourself
async function* asyncGenerator() {

  yield Promise.resolve(1);

  yield Promise.resolve(2);

  yield Promise.resolve(3);

}

async function processAsyncData() {

  const arr = await Array.fromAsync(asyncGenerator());

}

processAsyncData();

Browser Support

Array.fromAsync() is supported in all major browsers:

Chrome 121Edge 121Firefox 115Safari 16.4Opera 107
Jan 2024Jan 2024Jul 2023May 2023Feb 2024

New Uint8Array Methods

Base64 and Hexadecimal Encodings for Uint8Array.

These new static methods facilitate working with binary data by adding direct conversion between Uint8Array objects and Base64 or hexadecimal strings.

This eliminates the need for external buffer modules or hacky window methods like btoa() and atob().

  • Uint8Array fromBase64() Creates a Uint8Array object from a base64-encoded string
  • Uint8Array toBase64() Returns a base64-encoded string from the data in an int8Array
  • Uint8Array fromHex() Creates a Uint8Array object from a hexadecimal string
  • Uint8Array toHex() Returns a hex-encoded string from the data in an int8Array

Uint8Array to/fromBase64()

Examples

Example Code

javascript
Try it Yourself
// Creating raw binary data

const bytes = new Uint8Array([72, 101, 108, 108, 111]); // "Hello"

// New ES2026: Direct string conversions

const base64String = bytes.toBase64();

console.log(base64String); // "SGVsbG8="

const hexString = bytes.toHex();

console.log(hexString); // "48656c6c6f"

// Reversing the operation

const restoredBytes = Uint8Array.fromBase64("SGVsbG8=");

Browser Support

to/fromBase64() is supported in all major browsers:

Chrome 140Edge 140Firefox 133Safari 18.2Opera 124
Sep 2025Sep 2025Nov 2024Des 2024Nov 2024

Uint8Array to/fromHex()

Examples

Example Code

javascript
Try it Yourself
let text = '5b749c868a25b35db7';

const arr = Uint8Array.fromHex(text);

Browser Support

to/fromHex() is supported in all major browsers:

Chrome 140Edge 140Firefox 133Safari 18.2Opera 124
Sep 2025Sep 2025Nov 2024Des 2024Nov 2025

Accurate Floating-Point Math

The Math.sumPrecise() Method fixes the classic 0.1 + 0.2 === 0.30000000000000004 floating-point problem when summing lists of numbers.

Example

Example Code

javascript
Try it Yourself
// Old Way: Inaccuracies accumulate

const items = [0.1, 0.2, 0.3];

const badSum = items.reduce((a, b) => a + b, 0);

myDisplayer(badSum);

// New ES2026 Way: Perfectly precise

const preciseSum = Math.sumPrecise(items);

myDisplayer(preciseSum);

Browser Support

Math.sumPrecise() is supported in all major browsers:

Chrome 147Edge 147Firefox 137Safari 26.2Opera 131;
Apr 2026Apr 2026Apr 2025Nov 2025Apr 2026

Interactive Code Examples

JS Example 1

javascript
Try it Yourself
JavaScript syntax and algorithm demonstration.
const userRoles = new Map();



// Old Way: Multi-line checks

if (!userRoles.has("admin")) {

  userRoles.set("admin", []);

}

userRoles.get("admin").push("Alice");



// New ES2026 Way: Single-line default insertion

userRoles.getOrInsert("admin", []).push("Bob");

userRoles.getOrInsert("admin", []).push("Charlie");



console.log(userRoles.get("admin")); // ['Bob', 'Charlie']

JS Example 2

javascript
Try it Yourself
JavaScript syntax and algorithm demonstration.
const precisionLossJSON = '{"id": 9223372036854775807}';



// New ES2026 Reviver: Accesses the raw source string before rounding

const data = JSON.parse(precisionLossJSON, (key, value, context) => {

  if (key === 'id') {

    return context.source; // "9223372036854775807" as a string

  }

  return value;

});



// New ES2026 Stringify: Outputs the unrounded big integer safely

const output = JSON.stringify({

  id: JSON.rawJSON("9223372036854775807")

});

JS Example 3

javascript
Try it Yourself
JavaScript syntax and algorithm demonstration.
Error.isError(new TypeError());   // true

Error.isError({ name: "Error" }); // false

JS Example 4

javascript
Try it Yourself
JavaScript syntax and algorithm demonstration.
try {

  throw new TypeError("Invalid format");

} catch (err) {

  // Old Way: Could fail across different window contexts

  console.log(err instanceof Error);



  // New ES2026 Way: Globally reliable

  console.log(Error.isError(err)); // true

}

JS Example 5

javascript
Try it Yourself
JavaScript syntax and algorithm demonstration.
// An async generator simulating a paginated API

async function* fetchPages() {

  yield;

  yield;

}



// New ES2026 Way: Resolves and flattens natively

const allData = await Array.fromAsync(fetchPages(), flatMap => flatMap);

console.log(allData); // [1, 2, 3, 4]

JS Example 6

javascript
Try it Yourself
JavaScript syntax and algorithm demonstration.
async function* asyncGenerator() {

  yield Promise.resolve(1);

  yield Promise.resolve(2);

  yield Promise.resolve(3);

}



async function processAsyncData() {

  const arr = await Array.fromAsync(asyncGenerator());

}



processAsyncData();