From: Boris Zbarsky [mailto:bzbar...@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.