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

Reply via email to