On Sep 26, 2009, at 11:28 PM, Maciej Stachowiak wrote:
There are methods, but I'm not optimistic that they will cause
property reflection to wither.
getItem/setItem/removeItem/key/clear methods, plus .length -- not a
balanced name-set stylistically, but usable to avoid collisions (my
key is named 'key', heh).
Agreed it looks nearly hopeless to herd developers toward always using
these methods instead of .myKey, etc.
If the number of places in the Web platform that require custom
delete behavior goes from 1 to 2, that's a lot less bad than going
from 0 to 1. So it won't accomplish much. However, I missed a spot
and it looks like custom deleters are also used by the DOMStringMap
interface, which is used to reflect data-* attributes. <http://dev.w3.org/html5/spec/Overview.html#domstringmap-0
> I don't think anyone has implemented that yet.
Horses still out the barn door and we didn't close it yet, I'm not
sure who to blame except "us" (would be barn-door closers, possibly in
charge of those horses -- but perhaps they're not even ours!).
I believe we could get rid of custom deleters from the Web platform
if Firefox and IE remove support for custom deleters in
LocalStorage, refuse to add it back, and refuse to implement it for
DOMStringMap. If that happened, I'm sure other browsers and the spec
would follow suit. I don't think I can convince my colleagues to
remove the behavior from WebKit if Gecko and Trident continue to
support it.
I'll see what the relevant Mozilla WebAPI hackers think, if they're
not reading this thread. At this point I suspect it is "too late", in
the sense that we'd be taking risks with plaform compatibility we
don't accept in our release version/compatibility plan.
What does typeof say for such a callable object?
I think it should probably say "object", though that's not
compatible with ES3 or current WebKit practice.
ES3 lets host objects choose "function" or "object" or any old string
("Implementation-dependent").
ES5 says:
Object (native or host and does implement [[Call]])
-> "function"
Object (host and does not implement [[Call]])
-> Implementation-defined except may not be "undefined", "boolean",
"number", or "string".
This is not an issue for DOM methods. It's an issue for interfaces
such as HTMLCollection and HTMLFormElement that support indexing by
function call syntax, for legacy compatibility reasons. Constructors
like XMLHttpRequest, Option and Image also do not inherit from
Function.prototype even though they are callable.
Right, thanks for clarifying that. DOM collection types, even if
callable (VBScript was to blame) are not function objects, and DOM
constructors, unlike chapter 15 built-in ES constructors, are not
generally function objects.
This seems winning since developers want not only sane typeof,
but .apply/call/bind.
It's definitely winning, and it may be possible to apply it to
global constructors that are also callable as a future improvement,
but it's probably not possible to make HTMLCollection or
HTMLFormElement inherit from the Function prototype, and I think it
would not be desirable either.
Why not for HTMLFormElement? Agree for HTMLCollection.
Perhaps it's sufficient to provide an API for altering the [[Call]]
and [[Construct]] behavior of an existing object without a first-
class syntax, following in the spirit of defineOwnProperty().
Something like foo.defineOperation("construct",
funcToCallWhenConstructing). This would address all of points 2 to
5, for ECMAScript implementations that wish to precisely replicate
DOM behavior. This approach could also be used for index getters/
setters/has-testers, general catchall getters/setters/has-testers,
removing either one of call or construct while retaining the other,
making call and construct do different things, and perhaps other
useses. And using a method instead of first-class syntax would let
scripts feature-test for this capability.
See http://wiki.ecmascript.org/doku.php?id=strawman:catchalls but note
objections there, as well as some alternatives discussed in es-disc...@mozilla.org
.
A MOP for catchalls that stratifies the hooks into mirage (by analogy
to mirror-based reflection) objects may be forthcoming; we'll see
(I'll let the experts say more). A dark horse, at this point, but hey,
those other horses made it out of the barn ;-).
For simple things like non-constructor functions one might prefer a
declarative form. As an implementor and a developer, I would --
mutation is a bitch to optimize in a VM, and to contain in one's "user
code". Also the meta-programming API seems likely to be more verbose
than the (still elusive, but stipulate that it must be concise)
hypothetical declarative syntax.
Ye olde Image and Option, at least, act like most built-in
constructors by constructing when called, at least in Gecko and I
think IE -- but not in WebKit (I just tested).
My testing seems to indicate not in IE. Likewise for XMLHttpRequest.
We should probably specify one way or the other whether these are
callable and stick to it. I am indifferent as to which behavior we
standardize on.
Me too, except if I had to do it all over again I would have worked
harder to make function-ness orthogonal to prototype, a mixin if you
will. At this point,
http://wiki.ecmascript.org/doku.php?id=harmony:spread
takes away the need to inherit .apply/call, leaving bind as something
that might better be a primitive operator that works for all callables.
I'm musing a bit here, bear with me. If we only hack incrementally,
and preserve backward compatibility with frankly dumb (or merely
hasty) design decisions (many mine!) then we'll probably make less
progress than if we try to rationalize old and new in a better
systematic design.
So I too am indifferent so long as we do make progress factoring
function-ness out of which-prototype, if you get what I mean.
Date needs the latter.
As do String, Number, Boolean and RegExp, if I recall correctly.
Indeed. More warts to avoid generalizing into a complexion. :-/
/be