By combining decorators and the ref
proposal, we could
conceivably end up with a workable solution for "friend"-like behavior with classes:
// a.js
import { B } from "./b.js";
@friend(ref B) // give B access to all private fields of A
class A {
#x;
}
// b.js
import { A } from "./a.js";
let backchannel;
@friend.accept(ref A, ref backchannel)
class B {
getX(a) {
return backchannel.get(a, "#x");
}
}
Using ref
would allow us to mostly avoid issues with circularity and TDZ (since it creates a reference to the binding
and not the value). The friend.accept
decorator effectively creates a link between A
and B
that is exposed via backchannel
.
The backchannel
object then lazily verifies that B
was granted friend access to A
.
Using a ref here is certainly a more ergonomic and robust approach than what's already possible, which is passing an object or array, and using mutation to communicate - or, by passing a callback that's invoked with
backchannel
(which is probably simpler).To clarify; this is a cleaner way for A and B to share privileged access, provided that both A and B already know about each other, but it can already be achieved without decorators or refs?