"Subclassing" basic types in DOM - best method?

Tab Atkins Jr. jackalmage at gmail.com
Tue Nov 20 12:08:11 PST 2012

On Tue, Nov 20, 2012 at 3:28 AM, Alex Russell <alex at dojotoolkit.org> wrote:
> Actually, looking at this IDL more closely, I see unneeded invariants
> causing most of the problem. If URLQuery subclasses Map (assuming we make
> this possible, which we should),

Already possible.  AWB posted code to WHATWG showing how.  The Map
constructor is set up to respond correctly to "Map.call(this);",
blessing the object with the appropriate Map data structure.

> it only needs to promise to hand back
> strings, not take them. The behavior can simply be defined as toString()-ing
> the contents when calling "getAll()". There's no reason to re-defined
> anything about Map here or prevent the normal Map methods from taking
> any/any as key/value pairs. That URLQuery might, in normal usage, behave
> this way is a decision for users of the API.

Nope, that's not good enough.  For example, you have to do input
cleanup (replacing lone surrogates with U+FFFD, escaping &, etc.)
which affects whether two keys are "the same".  This affects set()'s
replacing behavior, and add()'s coalescing behavior.  Heck, even
without extra cleanup, just the fact that it requires string keys
means you need to eagerly preserve the invariant - foo.set([1,2],
'bar') and foo.set('1,2', 'bar') should both set the same key.  So,
the stringifying must be eager.  Additionally, you *must* override the
plain method anyway, since (if the URLQuery is attached to a URL), it
synchronously adjusts the underlying URL as well.

However, if you do a normal subclass, then people can do silly things
like "Map.prototype.set(query, key, val);", which would skip
URLQuery's own set() method, avoiding the invariant preservation and
the URL manipulation.

We could avoid these problems by only "subclassing" in the sense that
URLQuery.prototype = new Map();  (or Object.create(Map.prototype)),
but not invoking the Map constructor and actually storing data in a
closure-hidden internal Map, so instanceof would work but using Map's
own methods wouldn't.

Or, we could ignore the whole thing, and just make sure that we
ducktype as a Map.  Anne is fine with either, as long as a resolution
is forthcoming in a reasonable amount of time (more or less, only
dependent on things that are already Harmony, such that we can just
apply them to the spec now, even if the actual impl will be magic
before the feature is implemented properly).


More information about the es-discuss mailing list