This introduces new syntax for grouped accessors and auto-accessors to classes and object literals.
A grouped accessor is a single declaration that contains either or both both of the get
and set
methods for an accessor.
An auto-accessor is a simplified variant of a grouped accessor that elides the bodies of the get
and set
methods and
introduces a private backing field used by both the getter and setter.
class C {
x {
get() { ... } // equivalent to `get x() { ... }`
set(value) { ... } // equivalent to `set x(value) { ... }`
}
}
const obj = {
x {
get() { ... }
set() { ... }
}
};
A grouped accessor is essentially a way to define either or both of the get
and set
methods of an accessor. This provides
the following benefits:
- The
get
andset
are logically grouped together, which can improve readability. - A decorator applied to the group can observe both the
get
andset
methods simultaneously, for example:function dec({ get, set }, context) { ... return { get, set, }; } class C { @dec x { get() { ... } set(value) { ... } }
The semantics of a grouped accessor are as follows:
- It is a syntax error if a grouped accessor shares the name of another member with the same placement on the class
(i.e.
static
vs. non-static
):class C { x { get() { ... } } set x(value) { ... } // Syntax error y { get() { ... } } y { set(value) { ... } } // Syntax error }
- A grouped accessor can specify either a
get
, aset
, or both in any order. - A grouped accessor cannot specify more than one
get
orset
. - Otherwise, they are defined on the class in the same way that the individual declarations would have been.
class C {
x { get; set; } = 1;
y { get; } = 2;
z { get; #set; } = 3;
constructor() {
this.#z = 4;
}
}
const obj = {
x { get; set; }: 1,
y { get; }: 2
}
An auto-accessor is a simplified version of a grouped accessor that allows you to elide the body of the get
and set
methods, and optionally provide an initializer. An auto-initializer introduces a unique private field on
the class which is wrapped by a non-private getter and optional non-private setter. #set
entry indicates a
private setter of the same name as the public member exists on the object and provides privileged access to set the
underlying value.
This provides the following benefits:
- Introduces accessors that can be overridden in subclasses without excess boilerplate.
- Provides a replacement for fields that allows you to observe reading and writing the value of the field with decorators.
- Allows you to perform initialization inline with the declaration, similar to fields.
Another area of investigation is in the possibility of introducing accessor and method shorthand definitions, similar to arrow functions:
class C extends Base {
#x = 1;
// constructors
constructor(x) => super(x, 2)
// methods
m() => this.#x++;
// accessors
get x() => this.#x;
set x(value) => this.#x = value;
// grouped accessors
y {
get() => this.#x;
set(value) => this.#x = value;
}
}
const { x { get: get_x } } = obj;
typeof get_x; // "function"