Test for [[Construct]] invocation (was: Re: Must built-in prototypes also be valid instances? (Was: Why DataView.prototype object's [[Class]] is "Object"?))

# Herby Vojčík (13 years ago)

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. at FooBrand};

private @FooBrand;
class Foo {
   constructor() {
        /* establish the internal Fooness of the instance */
        this. at FooBrand = true;
   }
}

} var iWillBeFoo = {}; Fooishness.FooFactory().constructor(iWillBeFoo); (here I missed .call)

In fact, it has its logic to newFoo. at 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. at FooBrand = true; return newFoo; } } Foo.isFoo = function (obj) {return Reflect.hasOwn(obj, at FooBrand)&& !!obj. at 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...

# Brendan Eich (13 years ago)

Herby Vojčík wrote:

It can be arguments.isConstruct, for example.

(One-handed Luke Skywalker voice:) NOOOOOooooooooo!!!!

# Herby Vojčík (13 years ago)

Brendan Eich wrote:

Herby Vojčík wrote:

It can be arguments.isConstruct, for example.

(One-handed Luke Skywalker voice:) NOOOOOooooooooo!!!!

Or whatever else, I just happened to write first thing where it could reside.

# Kevin Smith (13 years ago)

(One-handed Luke Skywalker voice:) NOOOOOooooooooo!!!!

: ) Another perfect response!

# Uli Riehm (13 years ago)

You ask jS how I do ask a class function: if (config is instanceof V.Construction) return; - please read how I'm doing such a class function: metadea.de/V/default.aspx#V_construct_and_your_class

It's really the only function syntax to do real OOP, in javaScript. I'd like to fork Function function but the main functionality is to check if it prototypes (prototyping), if it returns itself, undefined or throws an exception (functioning) or the function constructs the object instance (constructing). Read!

/Uli

From: Kevin Smith Sent: Tuesday, October 02, 2012 10:11 PM To: Brendan Eich Cc: es-discuss Subject: Re: Test for [[Construct]] invocation (was: Re: Must built-inprototypes also be valid instances? (Was: Why DataView.prototypeobject's [[Class]] is "Object"?))

(One-handed Luke Skywalker voice:) NOOOOOooooooooo!!!!

: ) Another perfect response!