Hi,
Yes, traits can serve as prototypes for objects, and it is intentional that Object.create works fine when using a trait as a prototype. In fact, if you don't want frozen objects, then that's exactly what Object.create is for (Trait.create creates "high-integrity" frozen objects, while Object.create creates "normal" JS objects).
However, what you *cannot* do is to create a trait *instance*, and then use the trait instance as the prototype of yet other objects. While it's true that this would avoid instantiating the methods per instance, it won't work because Trait.create automatically binds |this| to the trait instance, making it impossible for sub-objects to reliably override the methods (the |this| in the trait instance will not point to the child object).
Use Trait.create
to instantiate objects that should be considered "final" and complete. Use Object.create
to instantiate objects that can remain "abstract" or otherwise extensible. For "final" objects, as generated by Trait.create
, keep in mind that the this
pseudovariable within their methods is bound at instantiation time to the instantiated object. This implies that final objects don't play nice with objects that delegate to them (this
is no longer late bound for such objects). That's why we call them final: such objects should not serve as the prototype of other objects.
Hope this helps.
Cheers,
Tom