- From: Mark S. Miller <erights@google.com>
- Date: Wed, 6 Jul 2011 14:22:52 -0700
- To: Boris Zbarsky <bzbarsky@mit.edu>
- Cc: Allen Wirfs-Brock <allen@wirfs-brock.com>, Luke Hoban <lukeh@microsoft.com>, "es5-discuss@mozilla.org" <es5-discuss@mozilla.org>, public-script-coord@w3.org
- Message-ID: <CABHxS9hrBdvHdojt_o0vcRRyr4-shvCD3M_BFDWv+7Dha1wMqg@mail.gmail.com>
On Wed, Jul 6, 2011 at 1:56 PM, Boris Zbarsky <bzbarsky@mit.edu> wrote: > On 7/6/11 4:42 PM, Mark S. Miller wrote: > >> The normative text is the more useful interpretation, in that access to >> a frame's setTimeout function should provide the ability to schedule a >> call to happen later, but should not provide access to that frame's >> global object. >> > > You can't do the former without having the latter. In particular, invoking > a frame's setTimeout function without the right |this| will throw. > > Of course you could be handed a prebound function which will invoke with > the right |this|.... On all the browsers I just tested, (1,setTimeout)(function(){'use strict'; alert('foo'); }, 0) alerts 'foo'. On what browsers are you seeing different behavior? > > The alternative, of changing the HTML5 spec to pass some global object >> explicitly, would require yet more hard to explain and emulate magic, >> since, for legacy compat, a setTimeout from frame X calling a callback >> from frame Y would need to explicitly pass Y's global object. >> > > This is true for non-strict-mode code already, right? Or am I > misunderstanding the problem? > I think you are. For the specified HTML5 behavior, when a setTimeout from frame X calls a non-strict callback from frame Y passing undefined as the thisArg, it is the non-strict callback's [[Call]] method that coerces the thisArg to Y's global object. Nothing requires X's setTimeout to be able to figure out what Y's global object is. > > The problem description strongly reminds me of > https://bugzilla.mozilla.org/**show_bug.cgi?id=634590<https://bugzilla.mozilla.org/show_bug.cgi?id=634590>by the way. That is a very interesting bug I hadn't been aware of. It does indeed look relevant. Will need some study. Thanks for pointing it out. > > > An emulated setTimeout written in JavaScript *could not* correctly emulate >> this behavior without introducing a generic way to get Y's global object >> from a frame Y closure. >> > > Again, you need that anyway to be able to setTimeout non-strict-mode > things, seems like. No. The setTimeout should just call the callback with undefined as the thisArg. If the callback is non-strict, it'll take care of the rest. > > > I think we should see this as yet more teething pains as browsers >> improve their ES5 implementations to be more conformant. In that >> context, given the HTML5 normative spec text above >> > > It's not clear to me that the HTML5 spec normative text is necessarily > correct. > > What do browsers set |this| to in a function if you define it in one frame > but then pass it to setTimeout in another frame and there's no strict mode > involved? Yes, this is the important legacy compat issue. We need to take a cross browser survey. > What does the ES5 spec say about that case? (Probably nothing, since it > assumes a unique global.) Correct. But our intent moving forward is clearly towards a lexical understanding of "which global". > > > The HTML5 normative text is actually quite clear -- that undefined is >> provided as the thisArg. >> > > It's clear, but it may still be wrong.... > If we can achieve consensus on something other than the normative, then sure, we can all agree the normative text is wrong. However, in this case, the normative text specifies a behavior that's clearly more useful than the alternative. > > -Boris > -- Cheers, --MarkM
Received on Wednesday, 6 July 2011 21:23:19 UTC