W3C home > Mailing lists > Public > public-script-coord@w3.org > January to March 2015

Re: A new hack for singleton objects

From: Olli Pettay <olli@pettay.fi>
Date: Tue, 17 Mar 2015 14:04:54 +0200
Message-ID: <55081866.2030604@pettay.fi>
To: Domenic Denicola <d@domenic.me>, "public-script-coord@w3.org" <public-script-coord@w3.org>
CC: Mounir Lamouri <mounir@lamouri.fr>, Alex Russell <slightlyoff@google.com>
On 03/17/2015 01:29 PM, Domenic Denicola wrote:
> I would like to get opinions from others on public-script-coord on this new "hack" I/Mounir thought up, for getting "singleton objects" of a sort
> while staying within the confines of WebIDL.
>
> ### Problem statement
>
> Many things on the platform are singletons. Examples: navigator.geolocation, navigator.battery, most things on navigator, window.history, many
> things on window. Idiomatic ES2015 would probably express these as modules. Idiomatic ES5 would likely express these as simply objects, IMO.
>
> All APIs today seem to express these as single instances of non-constructible classes, e.g. window.history is an instance of window.History, which
> cannot be constructed except by the UA. This is pretty weird (IMO),
It is somewhat odd yes.


> as classes should be for things you plan to create multiple instances of
not necessarily. Singleton instances of classes are rather common in other languages: make the ctor private and then
expose some static getFoo() to return the only instance.
Singleton instances can still behave as normal objects - say, the interface they are implementing can inherit EventTarget and the
instance works just like a normal EventTarget.

>, using
> its (working) constructor. In JS singleton classes are fairly silly; if you're only going to have one frobber in your project, just do `var frobber
> = { frob() { ... } }` instead of creating a whole `Frobber` class, guarding it so that the first time it's constructed it poisons itself against
> all future construction, and then saying `var frobber = new Frobber()`.
>
> ### Solution??
>
> The current design of the permissions API somewhat sidesteps this by making a `window.Permissions` interface which only has static methods and is
> non-constructible. This ends up behaving ... a lot like an object, or even module. It's non-callable, non-constructible, and has data properties
> which are functions. The only differences I see are: (a) it looks function-ey instead of object-ey, e.g. via `typeof` or `.constructor` or
> `instanceof` or `__proto__` (b) the capitalization implies to people that Permissions is a class, instances of which should either exist or be
> constructible. (For (b), the reasoning is: when I see `window.Text`, that is a hint that I will probably be able to create instances of `Text`.
> When I see `window.HTMLUnknownElement`, that is a hint that instances of `HTMLUnknownElement` will be created at least by the browser, if not by
> me.)
Well, depends on what "instances of" means. Sure, if you include the inheritance chain, you can create instances of EventTarget by just creating
an element or XMLHttpRequest. But creating pure EventTarget isn't possible.


>
> Of course, (b) could even be sidestepped by renaming the "interface" to be lowercase. This would give a `window.permissions` which is ... closer to
> idiomatic ES5 than `window.history` is, by my judgement.
>
> What do people think? Too crazy, or just crazy enough?


Not sure what you're asking for ;) Use of interfaces with static methods? Sounds ok to me. Allowing lowercase interface names? I guess that could
work, but should probably be limited to cases when the interface has _only_ static methods and attributes.


-Olli


>(Or, not crazy enough, i.e., we should just add namespace objects to WebIDL and get on with
> it? But nobody wants to block shipping new APIs on that, better to just wait until modules arrive I guess...)
>
Received on Tuesday, 17 March 2015 12:05:21 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 17 March 2015 12:05:21 UTC