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

Reply via email to