Changes to apply/call this coercion (was: ES3.1 Draft: 27 Oct 2008 version available)

# Robert Sayre (17 years ago)

Pratap Lakshman (VJ#SDK) wrote:

I have uploaded to the wiki (link es3.1:es3.1_proposal_working_draft) the 27 Oct 2008 draft of the specification for ES3.1. This is in the form of in-place edits and markups to the ES3 specification. Revision history is at the end of the document.

(I see multiple problems with these edits--I will address them separately)

These edits to call and apply look like unacceptable, incompatible changes to ECMAScript-262 3rd edition.

The following test passes in JS shells from Mozilla, WebKit, and Chrome:


this.foo = "bar";

function test(didPass, name) { print((didPass ? "PASS" : "FAIL") + " " + name); }

var f = function() { test(this.foo == "bar", "undefined/null thisArg"); }

var g = function() { test(this.foo == "qux", "thisArg supplied"); }

function testApplyAndCall() { f.apply(undefined, []); f.apply(null, []);

f.call(undefined); f.call(null);

var obj = {foo: "qux"};

g.apply(obj, []); g.apply(obj, []);

g.call(obj); g.call(obj); }

testApplyAndCall();

# Mark S. Miller (17 years ago)

On Mon, Oct 27, 2008 at 12:04 PM, Robert Sayre <sayrer at gmail.com> wrote:

Pratap Lakshman (VJ#SDK) wrote:

I have uploaded to the wiki (link es3.1:es3.1_proposal_working_draft) the 27 Oct 2008 draft of the specification for ES3.1. This is in the form of in-place edits and markups to the ES3 specification. Revision history is at the end of the document.

(I see multiple problems with these edits--I will address them separately)

These edits to call and apply look like unacceptable, incompatible changes to ECMAScript-262 3rd edition.

The following test passes in JS shells from Mozilla, WebKit, and Chrome:

You are completely correct, and all the folks editing the ES3.1 spec are in complete agreement. The bug you point out in the spec is my fault. It is an artifact of a partially completed refactoring of the spec, exactly along the lines we've all already discussed on the es*-discuss lists and verbally at the various meetings. The intent is the following:

  • All the coercions of the this-value that were scattered all over the spec, including in the apply and call language, be removed. This-arguments become this-values with no coercion.

  • When a function is called as a function, the implicit this-value provided is |undefined|.

  • A non-strict function's [[Call]] method (rather than it's |call| or |apply| methods) coerce the this-value on entry to preserve ES3 semantics. Since the time of coercion is unobservable (the coercion has no observable side effects), the intended result is no observable difference for non-strict functions. The non-strict this-coercions are:

** null -> global object ** undefined -> global object ** primitives -> wrappers (via ToObject)

  • Strict functions don't coerce their this-value at all. If your |f| and |g| functions were strict, then your test case must indeed fail. But if they're non-strict, your test case must pass

And again, sorry for the confusion!