The initializer
function mostly makes sense if you consider the proposal-class-fields TC39 proposal.
Consider the following code:
class C {
prop = {};
}
const a = new C()
const b = new C()
console.log(a.prop === b.prop)
You would expect the output to be false
.
For that reason, the "value" of the property cannot be stored as a static value
, but must instead be encoded as a function that returns a new value (here, an empty object) every time.
That code gets transpiled to something equivalent to:
class C {
constructor () {
const propName = 'prop'
const propDesc = Object.getOwnPropertyDescriptor(this.constructor.prototype, propName)
this[propName] = propDesc.initializer.call(this)
}
}
This also allows you to reference this
while declaring other instance variables (still in the context of that proposal):
class C {
entries = [ 1, 2, 3 ];
count = this.entries.length;
}
Since class C
is basically syntactic sugar for writing C.prototype
, decorators on class properties, are actually the same as decorators on object properties (the object being the prototype in this case).
The initializer
pattern allows for a single way of writing decorators in both these cases.