Open
Description
Proposal Readme
Proposal Spec Text
Tests
-
Fields
- Context
kind
is"field"
- Received value is
undefined
- Decorator can return an initializer function that receives the initial value and can return a new value, or
undefined
. Any other type of return value besides throws an error - Initializer functions for fields with multiple decorators are run in the reverse order of decorator evaluation (e.g. lexical order), and each initializer receives the return value of the previous initializer as its input
- Decorated field initializers are interleaved lexically with non-decorated field initializers
- Instance
- The
this
value of the initializer function is the instance of the class that is being initialized - Initializers is called at the same time as when the class field would be assigned if not decorated (e.g. right after
super()
, in lexical order)
- The
- Static
- The
this
value of the initializer function is the class definition itself - Initializers are called at the same time as when the class field would be assigned if not decorated (e.g. ordering is the same relative to static class blocks, computed name evaluation, etc.)
- The
- Context
-
Methods
- Context
kind
is"method"
- Received value is the class method function, or the function returned by the previous decorator applied to the method (if any)
- Decorator can return a function or
undefined
. Any other type of return value throws an error - The returned function is assigned in the same location as a non-decorated version would have been (e.g. on the class prototype for instance methods, on the class itself for static methods)
- If the decorator returns
undefined
, it assigns the original method OR the output of the most recent decorator which returned a function
- Context
-
Getters/Setters
- Context
kind
is"getter"
or"setter"
- Received value is the class getter/setter function, or the function returned by the previous decorator applied to the method (if any)
- Decorator can return a function or
undefined
. Any other type of return value throws an error - The returned function is assigned in the same location as a non-decorated version would have been (e.g. on the class prototype for instance getters/setters, on the class itself for static getters/setters)
- If the decorator returns
undefined
, it assigns the original getter/setter OR the output of the most recent decorator which returned a function
- Context
-
Auto-Accessors
- Behavior
-
accessor
keyword can be used to create an "empty" getter/setter pair on the class. The getter and setter read from and set to a private slot, with no additional observable behavior. -
accessor
can be combined with private fields,static
, and computed property names, and works with all permutations of them -
accessor
can be given an initializer that provides a default value - Initializers run at the same time as class fields, and are interleaved lexically with class field initializers
-
- Decoration
- Context
kind
is"accessor"
- Received value is an object with
get
andset
properties which are the getter and setter of the accessor, or the most recent decoration that returned one. - Decorator can return an object containing
get
,set
, and/orinit
properties. Each of these must be a function, any other type of value will throw an error - Decorator can return
undefined
, in which case previous value is used instead - If a previous decorator returns
get
but notset
,get
is replaced with the new value, and the previousset
is used - If a previous decorator returns
set
but notget
,set
is replaced with the new value, and the previousget
is used -
init
receives the initial value of the auto-accessor (or the returned value from the previousinit
) and may return a new value -
init
runs at the same time as a non-decorated accessor's initializer -
init
functions for multiple decorators on a single field run in the reverse order of decorator evaluation (e.g. lexical order), and each initializer receives the returned value of the previous initializer - The returned getter and setter are assigned in the same location as a non-decorated version would have been (e.g. on the class prototype for instance accessors, on the class itself for static accessors)
- If the decorator returns
undefined
, it assigns the original getter/setter OR the output of the most recent decorator which returned a value
- Context
- Behavior
-
Classes
- Context
kind
is"class"
- Class decorators receive the class definition, and may return a new construct-able value (e.g. another class, a proxy, a non-arrow function), or
undefined
- Class decorators are applied before static elements are evaluated, static blocks are called, etc.
- If the returned value cannot be constructed, throw an error
- Class declarations can be decorated
- Class expressions can be decorated
- Bindings to the class itself within the class definition reference the final class definition (e.g. the value returned by the last decorator)
- Context
-
Context
-
name
- Name is correct for standard public elements
- Name is the same as the name in code for private values (e.g.
#foo
) - Name is correct for computed property names
- Name is correct for classes
-
access
- Access includes
get
andset
functions -
get
andset
functions must be called withthis
value to work properly - Access works for public elements
- Access works for private elements
-
get
andset
access the method itself for methods/getters/setters (e.g. the slot that contains the method, public or private). This allows a decorator to get the final version of the method, for instance. -
set
does NOT work for private class methods/getters/setters - Not defined for classes
- Access includes
-
private
-
true
for private elements -
false
for public elements - Not defined for classes
-
-
static
-
true
for static elements -
false
for non-static elements - Not defined for classes
-
-
addInitializer
- Can receive a function as its first argument, throws an error if it receives any other type of value
- Methods/Getters/Setters: Extra initializers run immediately before class fields/accessors are assigned
- Fields/Accessors: Extra initializers run after the standard initializers are run and initial value is assigned
- Classes: Extra initializers run after class definition has completed, after static fields and elements have been assigned, just before the next statement or expression after the definition is run.
- Initializers run in the same order as decorator application (e.g. reverse lexical per element, lexical across all elements)
-
addInitializer
throws an error if called after decoration has finished (including if decoration was interrupted by an error)
-
-
General
- Syntax
- Application
- Decorators can be single identifiers (e.g.
@foo
) - Decorators can be single call expressions (e.g.
@foo()
) - Decorators can be a chain of property accesses (e.g.
@foo.bar.baz
) - Decorators can be a chain of property accesses with a call expression at the end (e.g.
@foo.bar.baz()
) - Decorator property accesses can include private names (e.g.
@foo.#bar
) - Any other expression can be wrapped in parens at the top level, examples:
-
@(foo().bar)
-
@(foo[0])
-
@(super.foo)
-
@(this.foo)
-
@(yield foo)
-
@(await foo)
-
- Any other syntax is invalid
- Decorators can be single identifiers (e.g.
- Placement
- Can be placed just before a class element
- Can be placed just before a class declaration or expression
- Are placed before
export
anddefault
keywords if they are applied to the class
- Application
- Ordering
- Decorators are applied to each element/class from inner to outer (reverse lexical)
- Decorators run in the order: Static non-fields -> Instance non-fields -> Static fields -> Instance fields -> Class
- Decorator expressions (e.g. the
dec()
part of@dec()
) are run before application, before static block initialization, interleaved and at the same time as computed expression name evaluation
- Decorators can be applied to all valid types of class elements (except static blocks)
- private
-
static
-
async
- generator
- Syntax
Metadata
Metadata
Assignees
Labels
No labels