On Oct 2, 2012, at 10:52 AM, Herby Vojčík wrote:
>
>
> Allen Wirfs-Brock wrote:
>>
>> If you really need to strongly tie instantiation with branding you
>> probably have to use a factory function:
>>
>> module Fooishness {
>> export function FooFactory ( ){return new Foo};
>> FooFactory.isFoo = function (obj) {return !!obj.@FooBrand};
>>
>> private @FooBrand;
>> class Foo {
>> constructor() {
>> /* establish the internal Fooness of the instance */
>> this.@FooBrand = true;
>> }
>> }
>> }
>
> var iWillBeFoo = {};
> Fooishness.FooFactory().constructor(iWillBeFoo);
>
> In fact, it has its logic to `newFoo.@FooBrand = true;` in factory, which
> solves it, hopefully cleanly enough.
>
>> Allen
>
> Herby
>
Good catch, I forgot that the constructor is still exposed as a property on the
instance. The other way to prevent the constructor from being used to brand a
pre-existing object is force an instantiation inside the constructor:
private @FooBrand;
class Foo {
constructor() {
let newFoo = Object.create(Foo.prototype);
/* establish the internal Fooness of the instance */
newFoo.@FooBrand = true;
return newFoo;
}
}
Foo.isFoo = function (obj) {return Reflect.hasOwn(obj,@FooBrand) &&
!!obj.@FooBrand};
But this prevents Foo branding of subclasses of Foo. There is a tension here
that I don't think is necessarily resolvable. To me, it is another example why
such class branding should only be used in specific high integrity situations
and not as a general practice for all classes.
Allen
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss