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 wrote:
It can be
arguments.isConstruct, for example.
(One-handed Luke Skywalker voice:) NOOOOOooooooooo!!!!
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.
(One-handed Luke Skywalker voice:) NOOOOOooooooooo!!!!
: ) Another perfect response!
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!
Allen Wirfs-Brock wrote:
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.Herby
P.S.: Alternatively, this line can be intrinsic property of class constructor, but this makes class special and not a desugaring any more...
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...