Here is the original quiz. #6 asks for the output of this code:
var foo = {
bar: function() {
return this.baz;
},
baz: 1
};
(function(){
return typeof arguments[0]();
})(foo.bar);
Knowing what this evaluates to requires that we understand
- How
this
late binds during a function invocation. - The array-like
arguments
object.
In the following code, what is the value of this
?
var foo = {
bar: function() {
return this.baz;
},
baz: 1
};
Trick question. We have no way to know what the value of this
is since this
isn't bound until the function is invoked.
exception
These walk through some accurate-enough-for-now heuristics for understanding this
.
###6a
var foo = {
bar: function() {
return this.baz;
},
baz: 1
};
foo.bar;
//=>function() {
// return this.baz;
// }
Remember that foo.bar
is a reference to a function. No ()
, no execution.
Here is a more complete explanation.
###6b:
var foo = {
bar: function() {
return this.baz;
},
baz: 1
};
foo.bar();
//=> 1
When we see someObject.method()
, that's a method invocation. During a method invocation, this
is a reference to the receiver, or the thing on the left side of the dot.
###6c
var fooOne = {
bar: function() {
return this.baz;
},
baz: 1
};
var fooTwo = {
baz: 2
};
fooTwo.bar = foo.bar;
fooTwo.bar();
//=> 2
Just another reminder that this
doesn't bind at the definition, but at invocation. Never assume that you know what this
is referencing unless you see ()
.
###6d
baz = "globalBaz"
var foo = {
bar: function() {
return this.baz;
},
baz: 1
};
var bar = foo.bar;
bar();
//=> "globalBaz"
When you see functionName()
, that is a function invocation, not a method invocation. no dot, no method The distinction isn't pedantic horseshit, it's important. this
operates differently, it doesn't reference the thing on the left side of the dot, there is no dot. Instead, this
becomes a reference to the global object during a function invocation exception
- We don't know what
this
is until its function is invoked. - Method Invocation -
objectName.method()
-this
points to the thing on the left side of the dot - Function Invocation -
functionName()
-this
points to the global object
##Arguments
###6e
var func = function(arg1, arg2){
return arg1 + arg2;
};
func("one", "two", "three");
//=> "onetwo"
func("one");
//=> "oneundefined"
(arg1, arg2)
is the function's formal parameter list which both sounds fancy and is optional. Note that we can invoke functions with more or fewer arguments than the formal parameter list specifies.
###6f
var func = function(){
return arguments;
});
func("one", "two");
//=> ["one", "two"]
func();
//=> []
We can also use arguments
, the built in array-like object that holds the arguments our function was called with.
###6g
var foo = {
bar: function() {
return this.baz;
},
baz: 1
};
(function(){
return arguments[0];
})(foo.bar);
//=>function() {
// return this.baz;
// }
(function(){
return arguments[0];
})(foo.bar());
//=> 1
(function(){
return arguments[0]();
})(foo.bar);
//=> undefined
Now to put everything together. Remember to watch for ()
and to keep an eye on the dot.