What’s Next for JavaScript? Inside TC39’s Latest Proposals and Stage Progress
The article reviews TC39’s 2020 final meeting, outlines stage‑gate requirements, and explains key proposals—including Error‑cause, Module Blocks, Extensions, and Grouped Accessors—detailing their motivations, syntax, and potential impact on JavaScript development.
TC39 2020 Final Meeting Overview
The meeting concluded without any proposal advancing from Stage 2 to Stage 3 or from Stage 3 to Stage 4.
Stage 1 → Stage 2 Requirement
Advancing a proposal from Stage 1 to Stage 2 requires a draft of the full specification text.
Error‑Cause Proposal
The
causeoption adds an optional parameter to the
Errorconstructor that can hold any JavaScript value, mirroring similar features in C#, Java, and Python. It enables devtools to display the cause automatically, improving debugging experience.
<code>try {
return await fetch('//unintelligible-url-a')
.catch(err => {
throw new Error('Download raw resource failed', err);
});
} catch (err) {
console.log(err);
console.log('Caused by', err.cause);
}
</code>Stage 0 → Stage 1 Requirements
Find a TC39 champion.
Define the problem, need, and rough solution.
Provide examples.
Discuss API shape, algorithms, semantics, and implementation risks.
JavaScript Module Blocks Proposal
Current approaches to share code across workers (separate files, string‑based execution, function‑to‑string) are inefficient or unsafe. The proposal introduces isolated module blocks that are parsed once and can be imported by workers.
<code>let workerCode = module {
onmessage = function({ data }) {
let mod = await import(data);
postMessage(mod.fn());
};
};
let worker = new Worker(workerCode, { type: 'module' });
worker.onmessage = ({ data }) => alert(data);
worker.postMessage(module { export function fn() { return 'hello!' } });
</code>Extensions Proposal
Revives ideas from the abandoned Bind Operator, adding local‑scope extensions, accessor syntax, and a dedicated namespace to avoid clashes. Example extensions include
::toSet,
::allDivs, and
::flatMap.
<code>// Extend collection types
const ::toSet = function () { return new Set(this) };
const ::allDivs = function {
get() { return this.querySelectorAll('div') }
};
const ::flatMap = Array.prototype.flatMap;
const ::size = Object.getOwnPropertyDescriptor(Set.prototype, 'size');
let classCount = document
::allDivs
::flatMap(el => el.classList)
::toSet()
::size;
</code>The proposal also defines namespace‑based usage (
obj::namespace:extension) and aligns the precedence of
::with
.. Compared with the Pipeline Operator,
::passes the left operand as
this, enabling patterns such as async pipe extensions.
<code>const ::pipe = fn => fn(this);
let result = "hello"
::pipe(capitalize)
::pipe(exclaim); // "Hello!"
</code>Grouped Accessor Proposal
Allows getters and setters to be declared together in a concise syntax and supports decorator application on the combined accessor.
<code>class C {
x {
get() { … }
set(value) { … }
}
}
</code>@JackWorks: What would JavaScript look like if all TC39 proposals were merged?
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.