Every year, a new version of ECMAScript is released with the proposals which are officially ready. This means, that the proposals which have been accepted and reached stage 4 by the TC39 committee would be included in the specification of that year (assuming it hasn’t been published), and the others – are postponed to the next year.
What that’s mentioned above is a part of the TC39 process – which is responsible to make changes and add features to the ECMAScript specification.
So, here we go – the approved proposals for 2019, as of today.
Note: In case you haven’t tasted the features of 2018 yet – go over 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 have been 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, an ECMAScript JSON is a superset of JSON, by all means:
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. Whereas JSON strings accepts unescaped U+2028
and U+2029
characters, ECMAScript strings don’t accept:
// This produces invalid ECMAScript String (before ES2019):
eval('"
"');
// This is invalid as well:
eval('"
"');
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 will 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’ve 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
eval
string that would throw aSyntaxError
exception.
The proposed solution distinguishes between the following cases in order to determine the result of toString
:
- In case that’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.
- In case that’s a built-in function object or bound function object (a function which is created by
bind
method) – it returns aNativeFunction
string. - In case that’s a callable function object which isn’t user-defined – it returns a
NativeFunction
string. - In case that’s a dynamically generated function object, through the
Function
andGeneratorFunction
constructors – it returns a synthesized string of the appropriate code, which is created by the ECMAScript engine. - In all other cases, it throws a
TypeError
exception.
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 the followng (using V8 engine):
// function () { return __generator(this, function (_a) {
// return [2 /*return*/];
// }); }
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 have been reached stage 4, after this article was published:
- Object.fromEntries
- Well-formed JSON.stringify
- String.prototype.{trimStart,trimEnd}
- Array.prototype.{flatMap,flat}
- String.prototype.matchAll
- import()
- BigInt
- Promise.allSettled
- globalThis
- for-in mechanics
- Optional Chaining
- Nullish coalescing Operator
Upcoming Proposals
These are the proposals that have been reached stage 3 and probably will be included in the specification – right after these will be approved completely.
Here’s attached a list for the proposals in this stage:
- Legacy RegExp features in JavaScript
- import.meta
- Private instance methods and accessors
- Class Public Instance Fields & Private Instance Fields
- Static class fields and private static methods
- Hashbang Grammar
- Numeric separators
- Top-level await
- WeakRefs
- RegExp Match array offsets
- String.prototype.replaceAll
- Promise.any
Summary
We covered today all the proposed which have been approved, at present, and will be included as part of the ECMAScript 2019 specification.
Take a look at the examples:
Here’s the sample project.