Re: Does JS bound to <element> need to inherit from HTMLElement?

On Fri, Apr 19, 2013 at 11:55 PM, John J Barton <johnjbarton@johnjbarton.com
> wrote:

>
> On Thu, Apr 18, 2013 at 11:11 PM, Dominic Cooney <dominicc@google.com>wrote:
>
>> On Wed, Apr 17, 2013 at 12:01 AM, John J Barton <
>> johnjbarton@johnjbarton.com> wrote:
>>
>>> I wonder if there may be a "cultural" difference involved in our
>>> different points of view. As a C++ developer I think your point of view
>>> makes a lot of sense.  As a JavaScript developer I find it puzzling.  Given
>>> a JS object I can override its value getter and add new properties
>>> operating on the object or inheriting from it.
>>>
>>
>> I'm not sure what precisely you mean by "override its value getter", but
>> if you mean define a property on the instance itself, that is an
>> antipattern in JavaScript because it bloats every instance with an
>> additional property, instead of just one additional property the prototype
>> object. It also makes further metaprogramming difficult, because there are
>> n places to hook (n=number of instances) of uncertain location, compared to
>> one place to hook (the prototype involved in the "inheritance") with a
>> discernable location (Constructor.prototype).
>>
>> I'm not sure what precisely you mean by "inheriting from it", but if you
>> mean put the DOM object on the prototype chain of a JavaScript object
>> (apologies if that is not what you meant), that is problematic too.
>> Depending on where the additional properties are defined it could have the
>> same problems I outlined in the previous paragraph. I think it has the
>> additional problem for implementations of making call sites using objects
>> set up this way appear polymorphic, interfering with polymorphic inline
>> caches.
>>
>> This is also a problem in that DOM operations stop working, for example:
>>
>> var x = document.createElement('div');
>> var y = Object.create(x);
>> y.appendChild(document.createElement('span'));
>>
>> will throw TypeError because the receiver is not a DOM object. I believe
>> this is correct per Web IDL <http://www.w3.org/TR/WebIDL/#es-operations>
>> 4.4.7 step 2.
>>
>
> I meant monkey patching the prototype.  Particular implementations of host
> objects may not allow that, which we could fix with various tradeoffs.
> I'm only suggesting to keep an open mind to alternatives. Inheritance is a
> fine technology but not always appropriate.
>
> jjb
>

Monkey-patching the prototype has some obstacles.

You can monkey-patch a well-known prototype, like HTMLDivElement.prototype;
the problem with that is that every other DIV will gain your API. And it is
a shared namespace, so your patch may collide with another.

You can monkey-patch the prototype chain of a given instance. This is
basically what Custom Elements codifies. The reason the UA needs to be
involved is there are too many places in the wild where script can observe
an element before you've had a chance to patch it.


>
>>
>>> Pre-ES6, the number of failure modes in both paths loom large. Anyone
>>> looking at the end result won't be able to tell the difference.
>>>
>>
>> If I understood the alternative approaches proposed, I think the
>> differences are observable.
>>
>>
>>> Anyway the group seems keen on inheritance so I hope it works out.
>>>
>>>
>>> On Mon, Apr 15, 2013 at 11:24 PM, Dominic Cooney <dominicc@google.com>wrote:
>>>
>>>> On Sat, Apr 13, 2013 at 12:03 PM, John J Barton <
>>>> johnjbarton@johnjbarton.com> wrote:
>>>>
>>>>> While I completely understand the beauty of having any JS object bound
>>>>> to an <element> inherit functions that make that object 'be an element',
>>>>> I'm unsure of the practical value.
>>>>>
>>>>> To me the critical relationship between the JS and the element is JS
>>>>> object access to its corresponding element instance without global
>>>>> operations. That is, no document.querySelector() must be required, because
>>>>> the result could depend upon the environment of the component instance.
>>>>>
>>>>
>>>> The critical issue to me is that there is a canonical object that
>>>> script uses to interact with the element. With ad-hoc wrapping of elements
>>>> in JavaScript, there are two objects (the "native" element wrapper provided
>>>> by the UA and the object provided by the page author) which results in
>>>> tedium at best (I did querySelector, now I need to do some other step to
>>>> find the author's wrapper if it exists) and bugs at worst (the author's
>>>> wrapper is trying to maintain some abstraction but that is violated by
>>>> direct access to the native element wrapper.)
>>>>
>>>>
>>>>> Whether that access is through |this| is way down the list of critical
>>>>> issues for me. Given a reference to the element I guess I can do everything
>>>>> I want. In fact I believe the vast majority of the JS code used in
>>>>> components will never override HTMLElement operations for the same reason
>>>>> we rarely override Object operations.
>>>>>
>>>>
>>>> The Object interface is not terribly specific and mostly dedicated to
>>>> metaprogramming the object model, so it is not surprising that it isn't
>>>> heavily overridden.
>>>>
>>>> Elements are more specific so overriding their operations seems more
>>>> useful. If I design a new kind of form input, it's very useful to hook
>>>> HTMLInputElement.value to do some de/serialization and checking.
>>>>
>>>> Extending HTMLElement et al is not just about overriding methods. It is
>>>> also to let the component author define new properties alongside existing
>>>> ones, as most HTMLElement subtypes do alongside HTMLElement's existing
>>>> properties and methods. And to enable authors to do this in a way
>>>> consistent with the way the UA does it, so authors using Web Components
>>>> don't need to be constantly observant that some particular functionality is
>>>> provided by the UA and some particular functionality is provided by
>>>> libraries.
>>>>
>>>>
>>>>> So is the inheritance thing really worth the effort? It seems to
>>>>> complicate the component story as far as I can tell.
>>>>>
>>>>
>>>> I think it is worth the effort.
>>>>
>>>> --
>>>> <http://goto.google.com/dc-email-sla>
>>>>
>>>
>>>
>>
>>
>> --
>> <http://goto.google.com/dc-email-sla>
>>
>
>


-- 
<http://goto.google.com/dc-email-sla>

Received on Monday, 22 April 2013 01:14:24 UTC