Re: This binding and ES5 builtins

Interesting - this is not what I expected.  That interpretation implies that ES5 intentionally diverged from the behaviour that has been standard in all major browsers (until some starting changing recently) as far as I can tell.  Has there been previous discussion of the compatibility implications?

Note that for the original two test cases, here is the results I see - which seems to offer historical (and current) support for the alternative interpretation:

>> (1, Object.prototype.hasOwnProperty)('abc')
IE6: false, IE9: false, IE10: false, FF3: false, FF4: TypeError, Chrome13: false, Chrome14: false, Safari5: false, Opera11: false

>>  var f = Object.prototype.hasOwnProperty
>>  f('abc')
IE6: false, IE9: false, IE10: false, FF3: false, FF4: TypeError, Chrome13: false, Chrome14: TypeError, Safari5: false, Opera11: false

Saying that undefined should be passed to built-ins feels like it is strict mode bleeding out of the strict mode opt-in.  In non-strict, in practice, the "global object" (leaving aside multiple globals for now) is passed as this to unbound function calls, irrespective of whether they are  native, built-in or host functions.  Why is this being changed to undefined outside of strict mode?

I would expect that if 13.2.1 is not relevant to built-ins, then the built-ins should have some other spec section that accomplishes the relevant parts of 13.2.1, in particular, the this-binding fix-up.

Also, the note that "if a host supplied function is somehow converting this/undefined to the caller's global object it is doing something magical", is concerning.  As far as I understand, with multiple globals, the web-compatible behaviour is to pass the caller-side global.  Pushing the burden of managing this to something magical the host functions need to take care of feels like the wrong direction, given what standard practice appears to have been.

Luke

From: es5-discuss-bounces@mozilla.org [mailto:es5-discuss-bounces@mozilla.org] On Behalf Of Mark S. Miller
Sent: Thursday, July 07, 2011 9:07 AM
To: Allen Wirfs-Brock
Cc: public-script-coord@w3.org; es5-discuss@mozilla.org
Subject: Re: {Spam?} Re: This binding and ES5 builtins

[+public-script-coord] as it is relevant to recent threads there.
On Thu, Jul 7, 2011 at 3:20 PM, Allen Wirfs-Brock <allen@wirfs-brock.com<mailto:allen@wirfs-brock.com>> wrote:

On Jul 7, 2011, at 2:58 AM, Mark S. Miller wrote:


On Thu, Jul 7, 2011 at 7:40 AM, Brendan Eich <brendan@mozilla.org<mailto:brendan@mozilla.org>> wrote:
[...]
Where does ES5 stipulate that the [[Call]] internal method of built-in functions that are not constructors is exactly the steps in the algorithm for each built-in function, and not 13.2.1?

Good question. The spec should be clearer about that.


Lasse's and Mark's interpretation of how calling built-in functions work is exactly the editorial intent.  This text:

This clause generally describes distinct behaviours for when a constructor is "called as a function" and for
when it is "called as part of a new expression". The "called as a function" behaviour corresponds to the
invocation of the constructor's [[Call]] internal method and the "called as part of a new expression" behaviour
corresponds to the invocation of the constructor's [[Construct]] internal method.

was also intended to mean that the [[Call]] internal methods of built-in-in functions are  exactly the behavior specified for the function in Clause 15.

The paragraph that precedes it probably needs to end with a sentence that says as much.  I'll add this as a 5.1 bug.

Relating this back to Luke's original question and setTimeout,  functions that are supplied by the host (regardless of whether you consider them to be host or native objects) must have [[Call]] and [[Construct]] behavior provided by the host as the 13.2.1 and 13.2.2 algorithms don't apply to them (as Lasse pointed out, at the very least they don't have [[Code]] internal properties that can be evaluated according to the rules of the specification)..   Whether a single  [[Call]]/[[Construct]] behavior is common to all such host supplied functions or different for each is an implementation detail.

This means that such functions (or an intervening host supplied [[Call]] implementation) are presented with the actual this value that was either explicitly or implicitly provided at the call site without any preprocessing.  Undefined is passed as undefined, primitive values are passed as unwrapped primitive values, etc. If any conversion of an undefined this value to a global object is going to take place for such functions in must take place within the function (or or an intervening host supplied [[Call]] implementation).  The ES spec. does not define any communications path by which a call site would communicate its current global object (if any) to such a function.  So if a host supplied function is somehow converting this/undefined to the caller's global object it is doing something magical.

Allen





--
    Cheers,
    --MarkM

Received on Friday, 8 July 2011 13:40:29 UTC