Frontend Development 11 min read

What’s New in JavaScript? Deep Dive into ShadowRealm, import defer, and More

This article reviews several upcoming JavaScript proposals—including the Stage 2.7 Error.isError method, the sandboxing ShadowRealm API, the import‑defer syntax for lazy module loading, as well as Iterator.zip, Iterator.concat, and Math.sumPrecise—detailing their motivations, usage examples, and potential impact on web and Node.js development.

Taobao Frontend Technology
Taobao Frontend Technology
Taobao Frontend Technology
What’s New in JavaScript? Deep Dive into ShadowRealm, import defer, and More

Stage 2 → Stage 2.7

Stage 2.7 is a newly added stage indicating that the proposal has effectively passed and the overall solution is complete; the next steps require test cases and vendor implementation feedback.

Error.isError

Proposal address: proposal‑is‑error

The proposal introduces a new global method

Error.isError

to reliably determine whether an object is an

Error

. The popular

is‑error

package (30 w weekly downloads) implements this check using

Object.prototype.toString() === '[object Error]'

.

ShadowRealm

Proposal address: ShadowRealm

This proposal adds a new JavaScript API that creates an isolated execution environment. ShadowRealm allows code to run in a separate context synchronously on the main thread, similar to Web Workers but without the asynchronous overhead. Its main goals are:

Introduce a new global object and related built‑in functions to manage program behavior in a specific execution environment.

Prohibit cross‑realm object access to enhance security and data isolation.

Provide each realm with an independent module dependency graph.

Enable synchronous communication between realms.

Typical use cases include:

Third‑party scripts such as web IDEs or same‑origin‑policy‑restricted code executors.

Code testing in an isolated realm to avoid test interference.

Separating code libraries into different realms to prevent conflicts.

DOM virtualization (e.g., Google AMP).

Unified virtualized API for browsers and Node.js (JSDOM + vm modules).

Virtualized environment where the global object can be customized.

DOM mocking with custom

globalThis

properties.

Example of creating a ShadowRealm and importing values:

<code>const shadowRealm = new ShadowRealm();

const [init, ready] = await Promise.all([
  shadowRealm.importValue('./pluginFramework.js', 'init'),
  shadowRealm.importValue('./pluginScript.js', 'ready'),
]);

init(ready);
</code>

Testing code in an isolated realm:

<code>import { test } from 'testFramework';
const shadowRealm = new ShadowRealm();

const [runTests, getReportString, suite] = await Promise.all([
  shadowRealm.importValue('testFramework', 'runTests'),
  shadowRealm.importValue('testFramework', 'getReportString'),
  shadowRealm.importValue('./my-tests.js', 'suite'),
]);

runTests(suite);
getReportString('tap', res => console.log(res));
</code>

Separating code libraries into different realms:

<code>const shadowRealm = new ShadowRealm();

const initVirtualDocument = await shadowRealm.importValue('virtual-document', 'init');
await shadowRealm.importValue('./publisher-amin.js', 'symbolId');

initVirtualDocument();
</code>

Freezing the global object inside a ShadowRealm:

<code>const shadowRealm = new ShadowRealm();
shadowRealm.evaluate('Object.freeze(globalThis), 0');
</code>

Using a module to freeze the global in a controlled way:

<code>const freezeRealmGlobal = await shadowRealm.importValue('./inside-code.js', 'reflectFreezeRealmGlobal');
freezeRealmGlobal();
</code>

Attempting to freeze an

iframe

window proxy fails, illustrating the advantage of ShadowRealm over traditional

iframe

isolation:

<code>const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
const rGlobal = iframe.contentWindow;
Object.freeze(rGlobal); // TypeError
</code>

DOM mocking example:

<code>const shadowRealm = new ShadowRealm();
const installFakeDOM = await shadowRealm.importValue('./fakedom.js', 'default');
installFakeDOM();
</code>

Customizing the global object inside a ShadowRealm:

<code>export default function() {
  const intrinsics = extractIntrinsicsFromGlobal(customGlobalThis);
  Object.defineProperties(globalThis, {
    document: createFakeDocumentDescriptor(intrinsics),
    Element: createFakeElementDescriptor(intrinsics),
    // ... other DOM globals
  });
}
</code>

Deferring Module Evaluation

Proposal address: Deferring Module Evaluation

In Node.js’s CommonJS system, avoiding unnecessary

require

calls is a common optimization. Dynamic

import()

can lazily load ES modules but does not solve synchronous execution delay. The proposal introduces a new syntax

import defer

that returns a module namespace object; the module is only synchronously loaded when a property of that object is accessed.

The module is loaded but not executed until needed.

Accessing a namespace property triggers synchronous execution if it has not yet run.

Async dependencies (using top‑level

await

) and their transitive dependencies must execute immediately to ensure their results are available synchronously.

Example execution order:

<code>// a
import "b";
import defer * as c from "c";

setTimeout(() => { c.value }, 1000);
</code>

Joint Iteration

Proposal address: Joint Iteration

The proposal adds

Iterator.zip

and

Iterator.zipKeyed

methods to align values from multiple iterators.

<code>Array.from(Iterator.zip([
  [0, 1, 2],
  [3, 4, 5],
])); // [[0,3],[1,4],[2,5]]
</code>
<code>Array.from(Iterator.zipKeyed({
  a: [0,1,2],
  b: [3,4,5,6],
  c: [7,8,9],
})); // [{a:0,b:3,c:7},{a:1,b:4,c:8},{a:2,b:5,c:9}]
</code>

Iterator Sequencing

Proposal address: Iterator Sequencing

This proposal introduces

Iterator.concat

to concatenate multiple iterators.

<code>let digits = Iterator.concat(lows, [4,5], highs);
</code>

Math.sumPrecise

Proposal address: proposal-math-sum

The proposal adds

Math.sumPrecise

, which sums a list using an algorithm equivalent to Python’s

math.fsum

, providing higher precision than the built‑in

+

operator.

<code>let values = [1e20, 0.1, -1e20];
values.reduce((a,b) => a + b, 0); // 0 (loss of precision)
Math.sumPrecise(values); // 0.1
</code>
JavaScriptiteratorsmodule loadingShadowRealmECMAScript proposals
Taobao Frontend Technology
Written by

Taobao Frontend Technology

The frontend landscape is constantly evolving, with rapid innovations across familiar languages. Like us, your understanding of the frontend is continually refreshed. Join us on Taobao, a vibrant, all‑encompassing platform, to uncover limitless potential.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.