Unlike decorating function expressions, decorating function declarations exposes us to a TDZ issue due to the hoisting that function declarations are subject to.
The TDZ issue can be resolved using Mirrors and if this proves to be an acceptable solution this proposal can be expanded to include function declarations as well.
@deco
let f() {}
@deco
const g() {}
Lazy evaluation (by @hax and revised by @rbuckton)
Make decorator evaluation lazy and apply it at one of two times (whichever comes first):
- When the function declaration is encountered during evaluation,
- The first time the function declaration is accessed as a value.
let g = f; // access f before declaration
f(); // invoke f before declaration
@deco function f() {
f(); // invoke f inside of declaration
}
Could be transpiled to:
let g = $$get_f(); // access f before declaration
$$get_f()(); // invoke f before declaration
function f() {
$$get_f()(); // invoke f inside of declaration
}
var $$f_decorated
function $$get_f() {
return $$f_decorated || $$f_decorated = deco(f);
}
$$get_f(); // eval decorator if not already accessed