John G Harris said:
If you did
var z = a[0];
z.("index");
I'm guessing this is a typo and it should just be
z("index")
what do you think the 'this' value will be while the function is
executing ?
The global object.
Why would it be different when you do
a[0]("index");
instead ?
Because that is how ECMAScript is specified.
There is no real difference between the function calls
a[0]("index")
and
b.foo("index")
and you would surely expect the latter to use the value of "b" as
the "this" value for the call.
In more detail:
When you evaluate a property accessor expression, e.g, a[0] or b.foo,
the immediate result of that is actually *not* the value of that
property, but a Reference value which contain both the base object and
the property name (see ECMA 262, section 8.7).
One advantage of this way of specifying the semantics of a property
access, is that it allows the same evaluation of a[0] whether or
not it happens on the left or right hand side of an assignment, e.g.,
a[0] = a[1]
That also makes it easier to specify the "delete" operator.
When a Reference value is used as a function, the value is looked up
and called, and the base object is used as the value of "this" (except
if its an activation object, i.e., the Reference came from evaluating
a local variable, then the base object is ignored so we don't expose
activation objects).
If a non-reference value is used as a function, there is no base
object, and the "this" value of the calle will be global object (see
ECAM 262 section 11.2.3).
That means that:
a[0]("foo")
calls the function on the reference a[0] (base object is the value of
"a" and property name is "0") as a function, which causes "this" to
refer to the value of "a" inside the function body.
However (if inside a function)
var z = a[0]; // only assignes value of reference, not the reference
z("foo");
will evaluate the variable "z", which does* give a reference, but with
the activation object as base object, so the value of "this" becomes
the global object during the call.
(In the global scope, "z" will evaluate to a real reference, but with
the global object as the base object, you won't be able to see the
difference
Remember that the 'this' value is calculated by the execution engine. It
uses a very simple rule and knows nothing about the complications in
your source code.
Actually, it does. It's a common cause of surprise, and as such it was
probably not a wise choice, but that is how ECMAScript is specified.
/L