In 2021, a number of proposals entered Stage 4 of TC39. In the TC39 process, each proposal starts at Stage 0, and moving to Stage 4 means that the proposal has been signed off by the ECMAScript editors and has become a de facto standard feature.
This article lists the 10 proposals that will enter Stage 4 in 2021 and will be incorporated into ECMAScript 2022.
Class Fields
Declares the fields of a class.
Proposal link: https://github.com/tc39/proposal-class-fields
Until now, in the ES specification, class fields were defined and initialised in the class constructor. However, in the new proposal, class fields can be defined and initialised at the top level of the class.
The proposal adds the features described in the following table to the ECMAScript Class (existing features in green).
The features included in the proposal are currently available in Chrome 74, Node 12, Safari Technology Preview 117, TypeScript 3.8, Babel 7.0+ and many more environments. However, it should be noted that because TypeScript, for example, had its own Class field implementation before the proposal officially entered Stage 4, the specific details of the semantics will differ from the preceding ECMAScript standard.
Private Fields, Methods
This proposal is part of the Class Fields family of proposals, which use the #
prefix to define private methods and fields of a class.
Proposal link: https://github.com/tc39/proposal-private-methods
|
|
Public Static Class Fields
Proposal link: https://github.com/tc39/proposal-static-class-features
Building on the previous class fields and private methods proposal, this proposal adds the features of Static public fields',
Static private methods’ and `Static private fields’ to JavaScript classes. The
Public Static Class Fields
Proposal link: https://github.com/tc39/proposal-static-class-features
Building on the previous proposals for fields and private methods for classes, this proposal adds Static public fields, Static private methods and Static private fields features to JavaScript classes.
Private Fields In Operator
Detects if private fields exist.
Proposal link: https://github.com/tc39/proposal-private-fields-in-in
Since attempting to access a private field that does not exist on an object raises an exception, there is a need to be able to check whether an object has a given private field.
This proposal provides the use of the in
operator to determine whether the field
introduced in the Class Private Fields proposal, which was formally introduced in Stage 4 recently, exists in an object. As opposed to directly accessing a private field by try { obj.#foo } catch { /* #foo not existing in obj */ }
to determine whether an object has a corresponding field
installed, Private-In can distinguish between an access error and the absence of a real field
, which would not be distinguished by try-catch in the following scenarios whether it is an access exception or whether the field
really does not exist.
And the semantics of the in
operator, which is similar to that of a normal field, determines whether a #field
exists on an object.
Class Static Initialization Blocks
Proposal link: https://github.com/tc39/proposal-class-static-block
Class Static Initialization Blocks provide a way of evaluating static initialization blocks during class declaration/definition, giving access to Class Private Fields.
Since the advent of Class Private Fields, there has been a constant flow of new practices and needs for class syntax. A similar capability for static initialisation blocks exists in languages such as Java, Static Initialization Blocks.
The initialization blocks defined in the proposal can acquire scope within the class, just like the methods of the class, and imply access to the # fields
of the class. With this definition, we can implement the Friend class in JavaScript.
|
|
Relative indexing .at() method
New .at() method on all built-in indexable data.
Proposal link: https://github.com/tc39/proposal-relative-indexing-method
This proposal provides a way to fetch elements from the beginning (forward indexing) or end (reverse indexing) of a string (or array) without using temporary variables.
In many cases, negative indexing of arrays like in Python is very useful. For example, in Python we can access the last element of an array via arr[-1]
instead of the current JavaScript method of arr[arr.length-1]
. Here the negative number is used as a reverse index from the starting element (i.e. arr[0]
).
But the problem in JavaScript now is that the syntax []
is not just used in arrays (and certainly not in Python), and it is not just used as an index in arrays. Referring to a value by index, as in arr[1]
, is in fact a reference to the "1"
property of the object. So arr[-1]
is already perfectly usable in today’s JavaScript engines, except that it may not mean what we want it to mean: it refers to the "-1"
property of the target object, rather than being an inverted index.
This proposal provides a generic solution, allowing access to any reverse-indexed, or forward-indexed, element via the .at
method on any indexable type (Array, String, and TypedArray).
Object.hasOwn
Proposal link: [https://github.com/tc39/proposal-accessible-object-hasownproperty](https://github.com/tc39/proposal-accessible-object- hasownproperty)
In short, the proposal is to use Object.hasOwn
instead of Object.prototype.hasOwnProperty.call
, a cleaner and more reliable way to check if a property is set directly on an object.
Error Cause
Proposal link: https://github.com/tc39/proposal-error-cause
Error Cause is a proposal by Alibaba and is claimed to be the first Chinese TC39 proposal to make it to Stage 4.
This proposal adds a new attribute cause
to the Error constructor in JavaScript, which allows developers to attach an error cause to a thrown error to clearly pass error context information across multiple call stacks. Specifically, the proposal adds an optional parameter options to the Error Constructor, which sets cause and accepts any JavaScript value (JavaScript can throw any value, such as undefined or a string), which is assigned to the newly created error.cause
.
|
|
RegExp Match Indices (’d’ Flag)
Proposal link: https://github.com/tc39/proposal-regexp-match-indices
The return value of the RegExp.prototype.exec
method in the current ECMAScript already provides the index in the regular expression for the text of the matching Capture Group and the corresponding Capture Group. However, in some cases we don’t just want to match text, we need to get the start and end position of the text being matched in the output text, for example, we need this information to provide syntax highlighting in development environments such as VS Code. Therefore, the RegExp Match Indices (’d’ Flag) proposal expects to add the indices
property to describe this positional information.
The above code would output the following.
Top-Level
Proposal link: https://github.com/tc39/proposal-top-level-await
ECMAScript 2017 introduces Async functions and the await
keyword, a feature that greatly simplifies the use of Promise. However, await
can only be used inside Async functions.
The new proposal Top-Level await
allows await
to be used outside of Async functions (e.g. CLI scripts, as well as dynamic import and data loading). This proposal treats ES Modules as large Async functions, so that these ES Modules can wait for resources to be loaded, so that other modules importing these modules will have to wait for resources to be loaded before they can start executing their own code.