On Sep 16, 2008, at 1:54 AM, Mark S. Miller wrote:
var funnyObj = {method: Date}
funnyObj.method(2008,9,11)
would bind funnyObj to |this| in Date, which would flow into the
constructor-case code as the new Date object to initialize.
Agreed that thsi proposal does not prevent this existing confusion.
Neither does it make it worse. If there's something we can
plausibly do to fix this, I'd love to! Any suggestions?
Not right now. Such a self-hosted Date could use instanceof to test a
|this| that was not undefined, and construct only if |this instanceof
Date| -- but it still act as a re-initializer of called on an
existing Date instance, e.g. d = new Date(2008,9,1); Date(d) -- still
not per-spec, but this is a problem for later.
This is also badly incompatible. Global functions are used as
methods of their window objects. Calling them via this.func() or
otherFrame.func() works, but so do calls to func() from the same
window.
Since there's only one window per JS global object (obviously,
since they're the same object), all the methods of the window could
already be bound to their window,
You're proposing to bind |this| to all window functions in strict mode?
and so not care what their 'this' is. However, that would break
code such as 'window1.func.call(window2)'. Currently, I expect func
will operate on window2; but if func is already bound to window1 it
will still operate on window1. Is this change of behavior a problem?
It could be; if you're talking about strict mode, it is yet another
migration tax hike, and a bit of an unwarranted extra complexity to
strict mode. What other this-binding does strict mode imply? I don't
remember anything like this.
I agree. I propose that primitive 'this' values not
be coerced at all.
This is a pretty big incompatibility. I'll scan some Ajax libraries
to look for obvious breaks. I suspect they'll be easy to find.
Any results?
No, I'm traveling and short on time and access. Maybe some of the
Prototype, Dojo, MochiKit, or JQuery folks on the list could help me
out and comment.
If the answer is that we can't avoid wrapping unconditionally, then
I propose that we wrap only on entry to non-strict functions, where
this wrapping is again cetralized in the spec to section 11.1.1.
Elsewhere you've written "more carrots, less sticks", with which I
heartily agree. If "strict" suppresses non-stratified reflection
that prevents many useful optimizations (with, delete <var>
(what about delete <var>? That it returns false should not prevent
optimizations...)
, arguments.caller, Function.caller, Function.arguments) and
removes pointless and costly wrapping,
Implements avoid wrapping, but sure: at some cost to implementation
complexity. Relieving that cost in strict mode does not remove the
complexity, though -- the default mode still requires (only for
interpreted functions, albeit lazy if the function mentions |this| or
|eval|) primitive-this wrapping.
then the common wisdom may become "Make your program work under
strict mode so it'll be faster."
Quality implementations won't get any faster.
I'm not sure what we are saving here. The point of strict mode is to
prevent bad practices and pitfalls, but adding scripted functions as
methods of standard prototypes, or otherwise arranging to call
methods on primitives, is not bad practice in my book. It's good
enough for s.charAt(i), why not for s.myCustomStringMethod()? One of
the use-cases for the new 3.1 Object methods is binding non-
enumerable prototype properties.
Yes. After ES3.1, I'd like to shift to your way of explaining it,
in terms of all values being objects. If we do this right, this
shift should only be a better way of explaining the same behavior.
The wrapping of primitive-this was still seen as required (optimized
to be lazy) for compatibility, even when ES4 had string, double,
boolean, etc value types in ES4. Breaking compatibility in ES3.1 and
future strict modes on this point seems independent of how one models
primitive types. Unless I'm missing something, we're only concerned
with whether to preserve primitive |this|, breaking compatibility,
when in strict mode; or else to wrap as in loose mode.
The spec has to wrap in loose mode. Implementations have to wrap
(lazily, if |this| is used, etc.) in loose mode. Implementations are
going crazy-fast these days and they avoid unnecessary wrapping, or
will shortly. What's the reason apart from "it'll be faster" to
change primitive |this| handling in strict mode, at a cost in spec
and implementation complexity?
/be
/be
_______________________________________________
Es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss