Closed
Description
Per consensus at the May, 2023 TC39 meeting, we need to change the evaluation order of decorator-injected initializers for both accessor
and non-accessor
fields. More details on the issue can be found here: tc39/proposal-decorators#508.
In summary, given
function minusTwo({ set }) {
return {
set(v) { set.call(this, v - 2); },
init(v) { return v - 2; },
};
}
function timesFour({ set }) {
return {
set(v) { set.call(this, v * 4); },
init(v) { return v * 4; }
};
}
class C {
@minusTwo @timesFour accessor x = 5;
}
const obj = new C();
console.log(obj.x); // (a)
obj.x = 5;
console.log(obj.x); // (b)
Prior to this change, the value at (a) would be 18 (((5) * 4) - 2
), while the value at (b) would be 12 (((5) - 2) * 4
). This is because the setters wrap and are thus evaluated from the outside-in, while initializers do not wrap and are applied from the inside-out.
After this change, the values at both (a) and (b) would be twelve, as the initializers would be applied outside-in as well.