Re: Strict mode callbacks and setTimeout

On Wed, Jul 6, 2011 at 1:56 PM, Boris Zbarsky <> 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
>**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

> -Boris


Received on Wednesday, 6 July 2011 21:23:19 UTC