"Subclassing" basic types in DOM - best method?

Domenic Denicola domenic at domenicdenicola.com
Tue Nov 20 06:25:42 PST 2012


For URLQuery in particular, since it's a String->String map, why not just use a plain-old-JavaScript-object with appropriate interceptions via a proxy? This provides a much more idiomatic API:

new URLQuery(object) stays the same
urlQuery.get(name) -> urlQuery[name][0]
urlQuery.getAll(name) -> urlQuery[name]
urlQuery.set(name, values) -> urlQuery[name] = values; use proxy here
urlQuery.add(name, values) -> urlQuery[name].push(...values); use proxy here
urlQuery.has(name) -> Object.prototype.hasOwnProperty.call(urlQuery, name)
urlQuery.delete(name) -> delete urlQuery[name]
urlQuery.delete(name, value) -> if (urlQuery[name]) { urlQuery[name] = urlQuery[name].filter(x => x !== value); }

"use proxy here" means use it to do argument validation and manipulation of the associated URL object, with percent-encoding.

The above assumes you want urlQuery[name] to always be an array; alternatively it could be either a string or array of strings, with appropriate magic behavior for either.
 

> -----Original Message-----
> From: es-discuss-bounces at mozilla.org [mailto:es-discuss-
> bounces at mozilla.org] On Behalf Of Tab Atkins Jr.
> Sent: Monday, November 19, 2012 18:16
> To: es-discuss
> Subject: "Subclassing" basic types in DOM - best method?
> 
> For several things in the DOM and related APIs, we want objects that are
> more-or-less the same as some basic ES stuff, like Arrays or Maps, and which
> are appropriate to treat as those objects in a generic manner.
> 
> For example, the URLQuery interface in the URL Standard
> <http://url.spec.whatwg.org/#interface-urlquery>, which represents the
> query portion (key/value pairs) of a URL, is basically a Map.  (It's missing a few
> pieces right now, like has() and the iterator-producing functions, but Anne
> plans to add them.)
> 
> Ideally, an author could take a library with generic Map-manipulating
> functions, pass a URLQuery object in, and have a reasonable chance of having
> that just succeed.  Hopefully, this should be robust to common type-checking
> operations, like doing a structural test, or an instanceof test.
> 
> Naively, this is doable just by subclassing Map (in the standard proto way),
> and overriding the methods, to delegate to the Map methods and then do
> additional things.  AWB posted some code to WHATWG detailing how you
> would do this in ES5 and ES6; it's predictably simple.
> 
> However, URLQuery has some invariants it needs to maintain: it's a
> String->String map, not Any->Any.  As such, it probably doesn't want
> to actually initialize itself as a Map and forward to the Map methods; instead,
> it should probably maintain a hidden internal Map and control the access to
> that itself, so it can ensure that no non-Strings leak into the map.
> 
> If we did this, the only reason to continue subclassing Map is to get instanceof
> checks to work.  Is this acceptable?  Are there better ways, perhaps on the
> horizon?  Any other thoughts?
> 
> (Further examples: NodeList being an Array, URLFragments being an Array, a
> few DOM->CSS bridges being Maps...)
> 
> ~TJ
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss



More information about the es-discuss mailing list