Last call: Function

Brendan Eich brendan at
Thu Mar 20 21:46:24 PDT 2008

On Mar 20, 2008, at 5:50 PM, Mark S. Miller wrote:

> * At the last ES-wide face-to-face, I thought we'd all agreed that the
> value of the thisObj argument to call/apply/bind, no matter what this
> value is, would be the value that gets bound to "this" in the called
> function. If I understand this proposed spec,, ...) would
> invoke f with its "this" bound to the global object.

I remember agreeing that the ES3 special case for null and undefined  
passed to Function.prototype.{apply, call} as the first actual  
parameter, where the null or undefined was replaced by "the global  
object", was confusing and error-prone. But it was not agreed that  
ES4 would incompatibly change this, although at least you and I  
entertained the idea.

I don't think we can remove this special case from engines handling  
unversioned or known-ES3/JS1.x-version content. Making yet another  
versioned change to the runtime semantics is not attractive at this  
point, compared to bigger fish to fry elsewhere that are entirely new  
and better, not bound by compatibility.

> That behavior
> makes JavaScript harder to secure, since this implicit access to the
> global object enable privilege escalation attacks.

This is true, but it's not peculiar to apply and call as Lars noted  
in reply. The ES3 |this| binding for inner functions called without  
an explicit |this| parameter is of course another case, and as far as  
I know the progenitor of the apply/call special case. Ticket 276, you  
well know (MILLEM-GOO :-P), deals with the |this| mess:

but it needs review and comments from others, including me (I'll get  
to it tomorrow).

> Such implicit
> access to the global object also prevents garbage collection
> opportunities: In a frame in which the global object were otherwise
> inaccessible, it would still need to be retained by any function that
> might be called so as to manufacture access to the global object.

Per ECMA-262 Edition 3 10.2.3, function objects already must capture  
their scope chains including the global object terminating the chain.  
In browsers, each window (tab), frame in frameset, and iframe has a  
global object. Cross-frame calls uphold static scope by following  
their [[Scope]] internal property's value to find the right globals,  
the ones lexically closed when the function and its surrounding code  
were loaded via a <script> tag.

Thanks for the reminder about all of "this". ;-)


More information about the Es4-discuss mailing list