proposal-mixins icon indicating copy to clipboard operation
proposal-mixins copied to clipboard

Evaluation time of computed property keys

Open justinfagnani opened this issue 7 years ago • 3 comments

As currently defined via desugaring to subclass factories, computed property keys are evaluated for each application:

mixin M {
  [(console.log('a'), 'a')]() { /* ... */ }
}
class A extends Object with M {}
class B extends Object with M {}

desugars to:

let M(base) => class extends base {
  [(console.log('a'), 'a')]() { /* ... */ }
}
class A extends M(Object) {}
class B extends M(Object) {}

This will evaluate the computed property expression twice, printing "a" to the console twice.

It's possible to evaluate the computed property keys just once, at mixin declaration time:

const __M_computed_key_1 = (console.log('a'), 'a');
let M(base) => class extends base {
  [__M_computed_key_1]() { /* ... */ }
}

This has some benefits and drawbacks, mostly around developer expectations:

  • It's consistent with class computed property keys, which are only evaluated once when the class is declared.
  • It's inconsistent with the explanation of mixins as subclass factories, whose bodies are evaluated for each application.

justinfagnani avatar Jan 28 '18 03:01 justinfagnani

cc @littledan

justinfagnani avatar Jan 28 '18 03:01 justinfagnani

This is a very clear summary of the trade-offs. I don't have much to add, just that potential future class features such as static field initializers, decorators and static blocks face similar issues of evaluation time.

littledan avatar Jan 28 '18 13:01 littledan

Although similar to function mixins, I think it makes more sense one evaluation per definition now that they are more like class definitions.

trusktr avatar Dec 06 '19 07:12 trusktr