Decorators for Stage 3

Chris Hewell Garrett


Refresher: What is a decorator?

Decorators are functions which have four main capabilities when applied to a class or class element

  • Replacement
  • Initialization
  • Metadata
  • Access

Refresher: Replacement

Decorators receive the original value, and can replace it with another value that has the same shape.

  • Methods can be replaced with a new method
  • Initial field values can be replaced with new values
  • Cannot change a field into a method, getter into a setter, etc. Has to be the same.
function wrapMethod(m) {
  return function() {

class C {
  @wrapMethod m() {

(new C).m();
// before
// method
// after

Refresher: Initialization

Decorators can run code to initialize the decorated value per-instance.

  • Method decorators can call `addInitializer`. Method initializers run before class fields are assigned.
  • Field decorators can run initialization code within the wrapped initializer
function bound(m, context) {
  context.addInitializer(function() {
    this[] = 

class C {
  x = 123;
  @bound m() {

const { m } = new C();

m(); // 123

Refresher: Metadata

Decorators can add metadata which is then readable by external code.

  • Metadata is defined via `setMetadata`
  • Metadata is keyed on a Symbol
  • Metadata is split between public and private
  • Metadata is inherited
  • Accessible on the class via `Symbol.metadata`
const MY_META = Symbol();

function addMeta(value) {
  return function(m, context) {
    context.setMetadata(MY_META, value);

class C {
  @addMeta('pub') x;
  @addMeta('priv') #x;

// 'class'
// 'pub'
// 'priv'

Refresher: Access

Decorators can provide access to the decorated value via `access` object

  • `access` object contains a getter that accesses the value if it is gettable (e.g. field, getter, method), and a setter if the value is settable (e.g. field, setter).
const EXPOSE = Symbol();

function expose(value, context) {
  context.setMetadata(EXPOSE, context.access.get);

class C {
  @expose x = 123;
  @expose #x = 456;

const c = new C();
const meta = C.prototype[Symbol.metadata][EXPOSE];; 
// 123
// 456

Refresher: Accessor Keyword

`accessor` can be used to create automatic getters/setters on a fiel

  • These getters/setters can then be decorated
class C {
  @reactive accessor foo = 123;  

Updates Since Last Meeting

  • `initialize` on accessor decorator return value renamed to `init`
  • `access` object included for public elements as well as private
  • `constructor` on metadata renamed to `own`
  • Spec has been fully written and updated, and has been reviewed by a number of members.

Asking for advancement to Stage 3