Published on 5 min read
ECMAScript - A Taste from ES2019 (ES10)
Every year, a new version of ECMAScript is released with the proposals that are ready. Proposals that reach stage 4 are included in that year’s specification, and the rest are postponed to the next one.
This is part of the TC39 process, which governs changes and additions to the ECMAScript specification.

Since 2024, there is also a Stage 2.7 between stages 2 and 3
So, here we go - the approved proposals for 2019, as of today.
Note: For the features of 2018, go over the respective guide.
Update: There are additional proposals which have been approved (check out the specified list below).
Approved Proposals
Just to clarify, these are the proposals that reached stage 4.
Optional Catch Binding
Until this proposal, the specification forced us to bind an exception variable for the catch clause whether it’s necessary or not:
function isValidJSON(text) {
try {
JSON.parse(text);
return true;
} catch(unusedVariable) {
return false;
}
}
Sometimes, as we see above, the exception variable that’s bound to the catch clause is absolutely redundant.
The proposal enables us to simply omit the variable including the parenthesis in such cases:
function isValidJSON(text) {
try {
JSON.parse(text);
return true;
} catch {
return false;
}
}
Subsume JSON
According to ECMAScript specification, ECMAScript was meant to be a superset of JSON:
After parsing, JSON objects are realized as ECMAScript objects. JSON arrays are realized as ECMAScript Array instances. JSON strings, numbers, booleans, and null are realized as ECMAScript strings, Numbers, Booleans, and null source).
But in practice, that’s not entirely true. JSON strings accept unescaped U+2028 and U+2029, but ECMAScript string literals didn’t:
// This produces invalid ECMAScript String (before ES2019):
eval('"\u2028"');
// This is invalid as well:
eval('"\u2029"');
Note: U+2028 represents LINE SEPARATOR and U+2029 represents PARAGRAPH SEPARATOR.
In simple words, this means there’s an inconsistency between valid JSON String and valid ECMAScript String, which could lead to potential bugs and specific handling in order to patch these gaps.
The proposed solution extends the ECMAScript strings so these accept U+2028 and U+2029.
Symbol Description Accessor
During the creation of a Symbol, it’s possible to specify a description which could be used later for debugging. In case we want to access the specified description, for instance, to reconstruct the symbol or just to log it - we have to extract it indirectly out of the toString value. 😕
The proposed solution adds a new read-only property, called description, which returns the optional description of a Symbol:
const symbol = Symbol('My Symbol!');
console.log(symbol.toString()); // Symbol(My Symbol!)
console.log(symbol.description); // My Symbol!
Function "toString" Revision
As we know, the toString method of a Function object doesn’t inherit directly from Object.prototype.toString, but overrides it.
For example:
// Before ES2019, it was depended on the engine:
console.log(function () { console.log('My Function!'); }.toString());
In ES2015, when toString was invoked on a function - one of the following occurred:
- It returned a string source code representation of the function, depending on the ECMAScript engine.
- In case the engine couldn’t produce a valid source code string - it returned an
evalstring that would throw aSyntaxErrorexception.
The proposed solution distinguishes between the following cases in order to determine the result of toString:
- If it’s a user-defined function object, which means, part of the source code - it returns a string containing the code which was used to define the function.
- If it’s a built-in function object or bound function object (a function which is created by
bindmethod) - it returns aNativeFunctionstring. - If it’s a callable function object which isn’t user-defined - it returns a
NativeFunctionstring. - If it’s a dynamically generated function object, through the
FunctionandGeneratorFunctionconstructors - it returns a synthesized string of the appropriate code, which is created by the ECMAScript engine. - In all other cases, it throws a
TypeErrorexception.
Let’s demonstrate each case:
// User-defined function object
// This prints "function () { console.log('My Function!'); }"
console.log(function () { console.log('My Function!'); }.toString());
// Build-in function object
// This prints "function parseInt() { [native code] }"
console.log(Number.parseInt.toString());
// Bound function object
// This prints "function () { [native code] }"
console.log(function () { }.bind(0).toString());
// Built-in callable function object
// This prints "function Symbol() { [native code] }"
console.log(Symbol.toString());
// Dynamically generated function object #1
// This prints "function anonymous() {}" (using V8 engine)
console.log(Function().toString());
// Dynamically generated function object #2
// This prints "function* () { }"
console.log(function* () { }.toString());
// This throws a TypeError: "Function.prototype.toString requires that 'this' be a Function"
Function.prototype.toString.call({});
Update: Additional Proposals
These are the proposals that reached stage 4, after this article was published.
Included in ES2019:
- Object.fromEntries
- Well-formed JSON.stringify
- String.prototype.{trimStart,trimEnd}
- Array.prototype.{flatMap,flat}
Included in ES2020:
- String.prototype.matchAll
- import()
- BigInt
- Promise.allSettled
- globalThis
- for-in mechanics
- Optional Chaining
- Nullish coalescing Operator
Upcoming Proposals
These are the proposals that had reached stage 3 when this article was published.
Update (September 2026): All of these proposals have shipped since, except for the legacy RegExp features, which are still at stage 3. The edition of each one is noted next to it.
Here are the proposals in this stage:
- Legacy RegExp features in JavaScript (still stage 3)
- import.meta (ES2020)
- Private instance methods and accessors (ES2022)
- Class Public Instance Fields & Private Instance Fields (ES2022)
- Static class fields and private static methods (ES2022)
- Hashbang Grammar (ES2023)
- Numeric separators (ES2021)
- Top-level await (ES2022)
- WeakRefs (ES2021)
- RegExp Match array offsets (ES2022)
- String.prototype.replaceAll (ES2021)
- Promise.any (ES2021)
Wrapping Up
We covered all the proposals approved for ECMAScript 2019.
Take a look at the examples:
Here’s the sample project.
You’re welcome to share:
Join My Newsletter
Get new posts directly to your inbox.
Comments are powered by DisqusDetails
Loading comments activates Disqus, which collects information as a third-party service.
The site owner has no access to or control over the information collected by Disqus.
Related Posts

How to Sync a Design System with Claude Design
18 min read
Syncing React components into Claude Design with /design-sync: what the mirror holds, how it's verified and a step-by-step example with shadcn/ui, Tailwind v4 and Storybook.

ECMAScript - Introducing Deferred Module Evaluation with import defer
8 min read
Introducing the “import defer” proposal, a new ECMAScript import form that loads and links modules eagerly while deferring their evaluation until a namespace property is first accessed - currently at stage 3 in the TC39 process.

ECMAScript - Introducing BigInt Primitive in ES2020 (ES11)
5 min read
BigInt in ES2020 (ES11) - a new primitive for arbitrarily large integers, with its operators, comparisons and limits.