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.
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.isErrorto reliably determine whether an object is an
Error. The popular
is‑errorpackage (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
globalThisproperties.
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
iframewindow proxy fails, illustrating the advantage of ShadowRealm over traditional
iframeisolation:
<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
requirecalls 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 deferthat 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.zipand
Iterator.zipKeyedmethods 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.concatto 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>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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.