RE: Defining a constructor for Element and friends

From: Boris Zbarsky [mailto:bzbarsky@mit.edu] 

>> "Terminology: In what follows I use 'own-instances of X' to mean objects where obj.constructor === X,
>
> That doesn't make much sense to me as a useful test, since it's pretty simple to produce, say, an HTMLParagraphElement instance on the web that has whatever .constructor value you desire, right?  Unless the intent is to talk about this in some setup where no one has messed with any of the objects or something.
>
> I guess the intent here is that we want obj to have been constructed via X in some sense?  Modulo whatever the story is for the things that have NamedConstructors.

Right, I was being imprecise. I am not sure how to make it precise. Maybe something like "was created via `new X`" assuming `X` doesn't use return-override and we buy in to the story where all instances are created via constructors (even those originating from the browser instead of the author).

> Anyway, modulo exactly what this definition should be, let's talk about the proposed "the constructor of an element determines its set of internal slots" invariant.  I'm OK with that if we include "constructor arguments".  Otherwise, I don't see how it can make sense.  In particular, say someone does:
>
>   var x = new Element("a", "http://www.w3.org/1999/xhtml")
>
> or whatever argument order we do.  Per invariant 1 in your document, this should get the internal slots of an HTMLAnchorElement, right?  Per invariant 2, x.constructor == Element, and in particular x.__proto__ == Element.prototype.  So suddenly we have an HTMLAnchorElement as an own-instance of "Element", which I think violates your invariant 3.

The idea is that your above example throws, preserving the invariant. Since there is already an entry in the registry for ("a", HTML_NS), and it's not Element, the constructor fails. (Except when invoked as part of a super() chain from the actual HTMLAnchorElement constructor.) Details:

- https://github.com/domenic/element-constructors/blob/88dbec40494aefc03825e00ff1bfc8d5e3f02f1e/element-constructors.js#L62-L66

- https://github.com/domenic/element-constructors/blob/88dbec40494aefc03825e00ff1bfc8d5e3f02f1e/element-constructors.js#L211-L215

> Moving on to invariant 4, is that "instances" in terms on instanceof (which can be almost tautologically true, given what Web IDL says about [[HasInstance]] on interface objects), or in terms of what the proto chain looks like, or something else?  In particular, the "x" defined above doesn't have HTMLElement.prototype on its proto chain, but is instanceof HTMLElement...

I was assuming non-exotic [[HasInstance]], but I agree it's ambiguous given that. I meant prototype chain. Probably I also implicitly meant internal slots.

> The one piece of terminology that I think we have so far that I understand is what it means for an object to "implement an interface". 
> At least Web IDL has a normative requirement on such a thing being defined (e.g. see http://heycam.github.io/webidl/#es-operations step 4 of the behavior), presumably in terms of some sort of branding.

Heh, I don't really understand what that means; I indeed noticed that Web IDL uses it without defining it.

I too would guess that it's branding-related. Note that in any sensible scheme I can think of, subclass instances (for a subclass that calls super() in the constructor) also get the brands of their superclass.

> So it makes sense to me to talk about things implementing Element but not any interface that has Element as an inherited interface.  That would correspond to "is an Element but not any specific subclass of Element".  Could use a shorter way of saying it, for sure.

Don't think this attempt at pinning down terminology works for user-defined subclasses of Element. E.g. as far as I can tell, `new (class X extends Element {})()` has only the Element brand but no other brand (since X didn't install any brands itself). But I would say that it's an own-instance of X instead of an own-instance of Element.

Received on Tuesday, 13 January 2015 17:06:28 UTC