This proposal adds decorators to JavaScript. It incorporates features needed to make decorators work with the class fields and private methods. See the explainer for an overview.
This document is phrased as a diff against the previous private methods proposal, which is in turn a diff against the class fields proposal.
"constructor"
.
The ElementDescriptor is a
Field Name | Value |
---|---|
[[Kind]] | One of "method" , "accessor" , "field" , or "hook" |
[[Key]] | A Property Key or |
[[Descriptor]] | A |
[[Placement]] | One of "static" , "prototype" , or "own" |
[[Initialize]] | A function or |
[[Start]] | A function. This field can be absent. |
[[Replace]] | A function. This field can be absent. |
[[Finish]] | A function. This field can be absent. |
[[Decorators]] | A |
In addition, given an ElementDescriptor element, the following conditions are always respected:
"method"
or "accessor"
, then
"field"
, then
"own"
or "static"
."hook"
, then
"method"
, then
"accessor"
, then
With parameters className and decorators.
constructor(... args){ super (...args);}
using the syntactic grammar with the constructor( ){ }
using the syntactic grammar with the "derived"
."constructor"
, F)."prototype"
, set placement to "own"
."method"
, [[Key]]: key, [[Descriptor]]: desc, [[Placement]]: placement}
With parameters homeObject, enumerable, and placement.
ClassElementEvaluation returns an
"prototype"
), enumerable, and "prototype"
."static"
."static"
and homeObject."own"
and ! "prototype"
)."prototype"
), enumerable, and "prototype"
.
"static"
.
"get"
)."prototype"
, set placement to "own"
."method"
, [[Key]]: key, [[Descriptor]]: desc, [[Placement]]: placement}
"set"
)."prototype"
, set placement to "own"
."method"
, [[Key]]: key, [[Descriptor]]: desc, [[Placement]]: placement}
"prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: "prototype"
, PropertyDescriptor { [[Value]]: prototype, [[Writable]]: With parameters placement and homeObject.
"field"
, [[Key]]: fieldName, [[Initialize]]: initialize, [[Descriptor]]: desc, [[Placement]]: placement}.
"name"
)."name"
).If the class definition included a name
static method then that method is not over-written with a name
data property for the class name.
"method"
or "accessor"
, and newElements contains a "method"
or "accessor"
, other.[[Key]] is element.[[Key]], and other.[[Placement]] is element.[[Placement]],"own"
, element.[[Kind]] is "method"
or "accessor"
, and element.[[Key]] is a Property Key,"own"
and element.[[Kind]] is "field"
,"hook"
and element.[[Placement]] is "own"
,"prototype"
)."static"
, element has a [[Key]] field, and element.[[Key]] is a Private Name,"method"
or "accessor"
, element.[[Placement]] is "static"
or "prototype"
, and element.[[Key]] is not a Private Name,"static"
, else let receiver be proto."field"
and element.[[Placement]] is "static"
or "prototype"
,"static"
, else let receiver be proto."prototype"
or "static"
and element.[[Kind]] is "hook"
and element has [[Start]],"static"
, else let receiver be proto."prototype"
or "static"
, element.[[Kind]] is "hook"
, and element has [[Replace]] or [[Finish]],"static"
."static"
, else let receiver be proto."field"
,"method"
,"accessor"
.Each Private Name immutably holds a mutable record called [[Attributes]], initially empty, which may have the following fields added to it:
Field | Type | For which types is it present | Description |
---|---|---|---|
[[Kind]] |
|
All | Indicates what the private name is used for. |
[[Brand]] | an ECMAScript value |
|
The "original" class of the private method or accessor; checked for in the [[PrivateBrands]] internal slot of instances before access is provided. |
[[Descriptor]] | PropertyDescriptor |
|
A property descriptor for the private field, method, or accessor, including the getter/setter for accessors and the value for methods. For fields, the descriptor determines whether it is writable. |
|
|
|
|
|
|
|
|
|
|
|
|
The Private Name constructor is the %PrivateName% intrinsic object. The %PrivateName% intrinsic does not have a global name or appear as a property of the
The
When
When PrivateNameObject is called with Private Name name, the following steps are taken:
"frozen"
).The %PrivateNamePrototype% object is an ordinary object. It is not a
The initial value of PrivateName.prototype.constructor
is the intrinsic object
When invoked, the following steps are taken:
%PrivateNameSet% is a per-
The following steps are taken:
The following steps are taken:
get
and set
methods.
The initial value of the @@toStringTag property is the String value "PrivateName"
.
This property has the attributes { [[Writable]]:
The abstract operation CreateIntrinsics with argument realmRec performs the following steps:
"frozen"
)."frozen"
)."prototype"
property, whose [[Value]] is %PrivateNamePrototype%."frozen"
).A decorator function is a function that takes and returns either a element descriptor or a class descriptor. The body of a decorator function modifies and returns the descriptor it receives to change the semantics of the decorated entity. Descriptor types can be differentiated by their kind
property, which is either "method"
, "accessor"
, "field"
, or "class"
. Descriptors also have a @@toStringTag property which has the value "Descriptor"
; this property helps differentiate them from other objects.
With parameters element, a Class Element, and placements:
"hook"
, throw a With parameters elements, a
"hook"
"hook"
"own"
, then"static"
, then"prototype"
."own"
, then"static"
, then"prototype"
."Descriptor"
, [[Writable]]: "kind"
, element.[[Kind]])."method"
, element.[[Descriptor]].[[Value]])."writable"
, element.[[Descriptor]].[[Writable]])."get"
, element.[[Descriptor]].[[Get]])."set"
, element.[[Descriptor]].[[Set]])."enumerable"
, element.[[Descriptor]].[[Enumerable]])."configurable"
, element.[[Descriptor]].[[Configurable]])."method"
, "accessor"
, or "field"
,"key"
, key)."placement"
, element.[[Placement]])."field"
,"initialize"
, initialize)."hook"
,"start"
, start)."extras"
)."enumerable"
)."configurable"
)."method"
)."method"
)."writable"
)."get"
)."get"
)."set"
)."set"
).With parameter elementObject, returns an
"kind"
))."hook"
, "method"
, "accessor"
, or "field"
, throw a "key"
)."hook"
,"placement"
))."static"
, "prototype"
, or "own"
, throw a "prototype"
, throw a "accessor"
or "hook"
and "field"
, "method"
or "hook"
, and "field"
and descriptor has a [[Value]] field, throw a "initialize"
)."field"
,"start"
)."hook"
,"replace"
)."hook"
,"finish"
)."hook"
,"hook"
,"own"
and either replace or finish is not "prototype"
and replace is not "elements"
)."method"
, "accessor"
, or `"field","field"
,"hook"
,With parameter elementObject, returns a
"extras"
)."Descriptor"
, [[Writable]]: "kind"
, "class"
)."elements"
, elementsObjects)."kind"
)."class"
, throw a "key"
)."placement"
)."initialize"
)."start"
)."extras"
)."finish"
)."replace"
)."elements"
)).An ECMAScript
eval
is a Function
, Generator
, AsyncFunction
, and AsyncGenerator
constructors is strict mode code if the last argument is a String that when processed is a ECMAScript code that is not strict mode code is called non-strict code.
An ECMAScript implementation may support the evaluation of function exotic objects whose evaluative behaviour is expressed in some implementation-defined form of executable code other than via ECMAScript code. Whether a function object is an ECMAScript code function or a non-ECMAScript function is not semantically observable from the perspective of an ECMAScript code function that calls or is called by such a non-ECMAScript function.
© 2019 Daniel Ehrenberg, Jeff Morrison, Kevin Smith, Kevin Gibbons, Yehuda Katz, Brian Terlson
All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.