Let's look at the ECMAScript 5 specification for
Let obj be the result of calling ToObject passing the
this value as the argument.
And when we examine ToObject, we see a familiar entry in the table:
Argument Type Result
Undefined Throw a TypeError exception.
Object The result is the input argument (no conversion).
This suggests that Chrome's invocation of
b() has a
this value that is not
undefined, but other browsers do pass a
undefined, resulting in a
First we must examine how
this is set when we perform a function call (which EMCAScript refers to as a CallExpression):
- If Type(ref) is Reference, then
- If IsPropertyReference(ref) is
- Let thisValue be GetBase(ref).
- Else, the base of ref is an Environment Record
- Let thisValue be the result of calling the ImplicitThisValue concrete method of GetBase(ref).
- Else, Type(ref) is not Reference.
- Let thisValue be
Because ImplicitThisValue of a function's Environment Record always returns
undefined, the only case in which
this is not
undefined is during property access, e.g.,
foo.bar(). Therefore, we can conclude that the execution of a "bare" function invocation like
b() will always use a thisValue of
But in the Chrome console,
b(). To understand how this could happen (and how it could differ between browsers), we need to examine strict mode behavior in Section 10.4.3, Entering Function Code:
The following steps are performed when control enters the execution context for function code contained in function object F, a caller provided thisArg, and a caller provided argumentsList:
If the function code is strict code, set the ThisBinding to thisArg.
Else if thisArg is
undefined, set the ThisBinding to the global object.
where "ThisBinding" is "The value associated with the
this keyword within ECMAScript code associated with this execution context."
Thus, non-strict code replaces an
undefined thisArg with the global object,
window. Strict mode, on the other hand, does not convert
undefined to the global object when used for
sort returns the sorted
this object, so
c = b() simply stores the returned the global object into
Therefore, we can conclude that Firefox's implementation of the
Array.prototype.sort function runs in strict mode, while Chrome's implementation does not.
You can see further evidence of this by how
sort handles non-object
this values. If oyu run
typeof ["sort"].apply(5) in various browsers, Chrome will output
"number", while Firefox outputs
"object", demonstrating the object autoboxing that occurs only in non-strict mode. Firefox's strict
sort function does not box the
5 and returns the raw primitive.