Re: Strict mode callbacks and setTimeout

[+public-script-coord]

On Wed, Jul 6, 2011 at 12:48 PM, Allen Wirfs-Brock <allen@wirfs-brock.com>wrote:

>
> On Jul 6, 2011, at 12:21 PM, Luke Hoban wrote:
>
> I recall there was some previous confirmation that the expected strict mode
> behaviour of this code was to alert 'undefined':
>
>  var f = function() { "use strict"; alert(this); }
>  f()
>
> However, what about similar code using setTimeout?
>
>  setTimeout(f,0)
>
> From HTML5 setTimeout [1], I see the following, which appears to be clear
> that the thisArg is 'undefined':
>
> "If the first argument to the invoked method is an object that has an
> internal [[Call]] method, then return a task that checks if the entry for
> handle in list has been cleared, and if it has not, calls the aforementioned
> [[Call]] method with as its arguments the third and subsequent arguments to
> the invoked method (if any), and with an undefined thisArg, and abort these
> steps. [ECMA262]"
>
> I would then expect ES5 10.4.3 to take care of setting 'this' to undefined.
>
>
> So would I.  However, the intent of the HTML5 spec. maybe that the Window
> object should be available in the handler as the this object (and to quote
> the HTML5 spec: "Note: Setting thisArg to undefined means that the
> function code will be executed with the this keyword bound to the
> WindowProxy<http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#windowproxy>or the
> WorkerGlobalScope object, as if the code was running in the global
> scope.")  If that is the intent then it should explicitly pass the
> appropiate this object rather than undefined as the thisArg.  This may be
> what the implementation you observed are doing.
>


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.
It is also the less unexpected behavior. The Note even is mostly correct,
needing only the substitution "... means that non-strict function code will
...".

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. 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.
Shudder.


>
> However, no current browser appears to alert 'undefined' in the second
> sample above, even those that do report 'undefined' for the first.
>
> 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, this bug is similar to the recently closed
<http://code.google.com/p/v8/issues/detail?id=1360>.



> Is the reasoning above correct?
>
> Yes.




>  Is 'undefined' the expected result of both examples?
>
> Yes.


> It would be if this was all pure ES code. But since it isn't the depends
> upon what HTML5 actually wants the result to be.  It's spec. needs to be
> more explicit in that regard.  It it wants something other than undefined as
> the this value it should say so.
>

The HTML5 normative text is actually quite clear -- that undefined is
provided as the thisArg. Only the note needs minor revision, as above.



>
>
>
> Thanks,
> Luke
>
> [1] http://www.w3.org/TR/html5/timers.html#get-the-timed-task
> _______________________________________________
> es5-discuss mailing list
> es5-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es5-discuss
>
>
>
> _______________________________________________
> es5-discuss mailing list
> es5-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es5-discuss
>



-- 
    Cheers,
    --MarkM

Received on Wednesday, 6 July 2011 20:42:37 UTC