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.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:
const shadowRealm = new ShadowRealm();
const [init, ready] = await Promise.all([
shadowRealm.importValue('./pluginFramework.js', 'init'),
shadowRealm.importValue('./pluginScript.js', 'ready'),
]);
init(ready);Testing code in an isolated realm:
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));Separating code libraries into different realms:
const shadowRealm = new ShadowRealm();
const initVirtualDocument = await shadowRealm.importValue('virtual-document', 'init');
await shadowRealm.importValue('./publisher-amin.js', 'symbolId');
initVirtualDocument();Freezing the global object inside a ShadowRealm:
const shadowRealm = new ShadowRealm();
shadowRealm.evaluate('Object.freeze(globalThis), 0');Using a module to freeze the global in a controlled way:
const freezeRealmGlobal = await shadowRealm.importValue('./inside-code.js', 'reflectFreezeRealmGlobal');
freezeRealmGlobal();Attempting to freeze an iframe window proxy fails, illustrating the advantage of ShadowRealm over traditional iframe isolation:
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
const rGlobal = iframe.contentWindow;
Object.freeze(rGlobal); // TypeErrorDOM mocking example:
const shadowRealm = new ShadowRealm();
const installFakeDOM = await shadowRealm.importValue('./fakedom.js', 'default');
installFakeDOM();Customizing the global object inside a ShadowRealm:
export default function() {
const intrinsics = extractIntrinsicsFromGlobal(customGlobalThis);
Object.defineProperties(globalThis, {
document: createFakeDocumentDescriptor(intrinsics),
Element: createFakeElementDescriptor(intrinsics),
// ... other DOM globals
});
}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:
// a
import "b";
import defer * as c from "c";
setTimeout(() => { c.value }, 1000);Joint Iteration
Proposal address: Joint Iteration
The proposal adds Iterator.zip and Iterator.zipKeyed methods to align values from multiple iterators.
Array.from(Iterator.zip([
[0, 1, 2],
[3, 4, 5],
])); // [[0,3],[1,4],[2,5]] 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}]Iterator Sequencing
Proposal address: Iterator Sequencing
This proposal introduces Iterator.concat to concatenate multiple iterators.
let digits = Iterator.concat(lows, [4,5], highs);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.
let values = [1e20, 0.1, -1e20];
values.reduce((a,b) => a + b, 0); // 0 (loss of precision)
Math.sumPrecise(values); // 0.1Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
