Perfection Kills Quiz (part 6)

Previous posts on Perfection Kills JavaScript quiz: 1, 2, 3, 4, 5.

6)

var foo = {
  bar: function(){ return this.baz; },
  baz: 1
};
(function(){
  return typeof arguments[0]();
})(foo.bar);

Correct answer: "undefined".

For simplicity, I will refer to the function function(){ return this.baz; } as Function A and to the function function(){ return typeof arguments[0](); } as Function B.

Function B is immediately invoked with the argument foo.bar, which evaluates to Function A. The whole snippet of code returns the value of typeof arguments[0]();, so we can focus just on this line.

It is tempting to believe that the statement return typeof arguments[0](); returns the same value as the statement return typeof foo.bar();. However, this is not true. Although both foo.bar and arguments[0] point to the same function, i.e. Function A, in those two cases the keyword this in the body of Function A refers to two different objects.

If foo.bar was invoked, the keyword this in Function A would refer to the object foo. This object has a property baz, and hence Function A would have returned the value 1 (a number).

It is important to understand that our snippet of code does not invoke foo.bar. When function B is invoked, the arguments object is created, and its [0] property points to Function A rather than foo.bar. When the line return typeof arguments[0](); is executed, the keyword this in Function A refers to the arguments object. As this object does not have a property baz, Function A returns undefined. Since typeof undefined is "undefined", the return value of our snippet of code is "undefined".

All posts on Perfection Kills JavaScript quiz: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14.