Allen Wirfs-Brock wrote:
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);
(here I missed `.call`)
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.
Well, here (and in other cases, too) it would be handy to be able to
distinguish whether the call is constructor (new operator, super() call
in class constructor) or plain call (the rest). It can be
`arguments.isConstruct`, for example.
Than, it would simply be solved by `if (!arguments.isConstruct) return;`
(or throw) as the first line in constructor.
Allen
Herby
P.S.: Alternatively, this line can be intrinsic property of class
constructor, but this makes class special and not a desugaring any more...
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss