Re: Exposing constructors of readonly interfaces to web authors

On Wed, Jul 2, 2014 at 5:10 AM, Boris Zbarsky <bzbarsky@mit.edu> wrote:

> On 7/1/14, 6:16 PM, Domenic Denicola wrote:
>
>> So if I understand correctly, you are saying that there are two different
>> functions being run when I do (new DOMQuad()).bounds.x and when I do (new
>> DOMRect()).x, but to JavaScript, since DOMQuadBounds has a different
>> implementation than DOMRect. But it looks like they are the same function
>> to JavaScript?
>>
>> How is this possible?
>>
>
> There are several things going on here.
>
> First of all, the prototopy chains for (new DOMQuad()).bounds) and (new
> DOMRect()) look like this:
>
>   (new DOMQuad()).bounds) -> DOMRectReadOnly.prototype
>
>   (new DOMRect()) -> DOMRect.prototype -> DOMRectReadonly.prototype
>
> In this case, there is a getter for the property named "x" on _both_
> DOMRect.prototype and DOMRectReadonly.prototype.  So when you do
>
>   (new DOMQuad()).bounds).x
>
> and
>
>   (new DOMRect()).x
>
> you are not in fact calling the same JS function.
>
> But that's an accident, more or less.  We could add a new property, call
> it "area" on DOMRectReadOnly.prototype that is not shadowed by DOMRect.
>  Getting .area on either of those objects would then call this same JS
> function.  What this JS function does in Gecko is extract the underlying
> C++ object (a DOMRectReadOnly in this case) and call a method on it.
>
> It so happens that in Gecko the DOMRectReadOnly C++ object only has pure
> virtual functions.  That is, it delegates all calls on it to subclasses.
>  Internally, (new DOMQuad()).bounds) and (new DOMRect()) instantiate
> different subclasses of DOMRectReadOnly, that have functions named "X" that
> have different implementations.
>
> So effectively, these two objects have an internal slot (the C++ vtable in
> this case, but you could do the same sort of thing in JS via symbols, say,
> or in C++ via a boolean member or some other polymorphism mechanism) that
> indicates what the getter should do when invoked with that sort of object
> as a this object.
>

This confirms that the current behavior can be implemented using JavaScript.
Doesn't this satisfy Domenic's requirement?


> Back to my "area" example, if we were to implement that, we would of
> course implement it directly on DOMRectReadOnly, not on subclasses, since
> all it needs is the already existing exposed API to compute its result..
>  So an "area" getter would not in fact be polymorphic.
>
> I can't speak to the desirability of this behavior.  Polymorphic behavior
> via introspection of the this value is not super-common in JS (not least
> because introspection is complicated) but is not unknown.  In fact, a
> number of ES6 algorithms support just that sort of polymorphism by
> delegating various tasks this.something, which allows subclasses to
> override the default superclass implementation in certain well-defined ways.


This is another argument that the current approach is doable. This should
settle our class inheritance and how attributes are readonly in the base
and read/write in the derived class.

Dominic also brought up that live objects are not desirable but everyone
disagreed there.

This leaves if the readonly objects should be constructable. I'd rather not
pollute the global namespace with a useless class but if this is a
requirement for good design, we can certainly make that change.

Could we also add a dictionary type that contains the attributes. Then we
can design DOM methods that take these dictionaries so people can pass in
the object or a dictionary.

Received on Friday, 4 July 2014 19:40:54 UTC