class OtherClass {}
class MyClass1 extends OtherClass {
publicInstanceField = 1;
constructor() {
super();
}
publicPrototypeMethod() {
return 2;
}
}
const inst1 = new MyClass1();
assert.equal(inst1.publicInstanceField, 1);
assert.equal(inst1.publicPrototypeMethod(), 2);
class MyClass2 {
static staticPublicField = 1;
static staticPublicMethod() {
return 2;
}
}
assert.equal(MyClass2.staticPublicField, 1);
assert.equal(MyClass2.staticPublicMethod(), 2);
class MyClass3 {
#privateField = 1;
#privateMethod() {
return 2;
}
static accessPrivateMembers() {
// Private members can only be accessed from inside class definitions
const inst3 = new MyClass3();
assert.equal(inst3.#privateField, 1);
assert.equal(inst3.#privateMethod(), 2);
}
}
MyClass3.accessPrivateMembers();
There are two kinds of accessors: getters and setters.
class MyClass5 {
#name = 'Rumpelstiltskin';
/** Prototype getter */
get name() {
return this.#name;
}
/** Prototype setter */
set name(value) {
this.#name = value;
}
}
const inst5 = new MyClass5();
assert.equal(inst5.name, 'Rumpelstiltskin'); // getter
inst5.name = 'Queen'; // setter
assert.equal(inst5.name, 'Queen'); // getter
class MyClass6 {
* publicPrototypeGeneratorMethod() {
yield 'hello';
yield 'world';
}
}
const inst6 = new MyClass6();
assert.deepEqual(
[...inst6.publicPrototypeGeneratorMethod()],
['hello', 'world']);
class MyClass7 {
async publicPrototypeAsyncMethod() {
const result = await Promise.resolve('abc');
return result;
}
}
const inst7 = new MyClass7();
inst7.publicPrototypeAsyncMethod()
.then(result => assert.equal(result, 'abc'));
const publicInstanceFieldKey = Symbol('publicInstanceFieldKey');
const publicPrototypeMethodKey = Symbol('publicPrototypeMethodKey');
class MyClass8 {
[publicInstanceFieldKey] = 1;
[publicPrototypeMethodKey]() {
return 2;
}
}
const inst8 = new MyClass8();
assert.equal(inst8[publicInstanceFieldKey], 1);
assert.equal(inst8[publicPrototypeMethodKey](), 2);
Comments:
- The main use case for this feature is symbols such as
Symbol.iterator
. But any expression can be used inside the square brackets. - We can compute the names of fields, methods, and accessors.
- We cannot compute the names of private members (which are always fixed).
Fields:
level | visibility |
---|---|
(instance) | |
(instance) | # |
static |
|
static |
# |
Methods:
level | async | accessor | generator | visibility |
---|---|---|---|---|
(prototype) | ||||
(prototype) | get |
|||
(prototype) | set |
|||
(prototype) | async |
|||
(prototype) | * |
|||
(prototype) | async |
* |
||
(prototype-associated) | # |
|||
(prototype-associated) | get |
# |
||
(prototype-associated) | set |
# |
||
static |
||||
static |
get |
|||
static |
set |
|||
static |
async |
|||
static |
* |
|||
static |
async |
* |
||
static |
# |
|||
static |
get |
# |
||
static |
set |
# |
Limitations of methods:
- Private methods can’t be async or generators.
- Getters and setters can’t be async or generators.