Elaboration on elclanrs' answer.
foo.bar
is a method; an instruction of how to do something. In object-oriented programming languages, the only object that can use that instruction is a foo
or an object related to foo
; but in JavaScript, anybody can try to run it if the code asks them to.
In your second anonymous function, you are getting a method to run, running it, and returning the type of the result. However, it's not a foo
that is running this function; it's anonymous, so the window
is the object that's running it. The window
runs foo
, which tries to return this.baz
; however, the window
doesn't HAVE a baz
, so that's why you're getting undefined.
To test it further, try setting window.baz
and see if you get the right result, and also try elclanrs' suggestion of using the call()
method to ensure it gets called from a foo
's scope.
EDIT
You're right, the type of arguments[0]
and foo.bar
IS the same; they're both "function". I think the confusion is over JavaScript's treatment of functions as first-class objects.
If you're familiar with object-oriented languages like Java or C++, then you would expect that when you call bar
, it's always being called by a foo
that has a baz
property; however, this isn't the case in JavaScript. Any function can be called by ANY object, which means the result may or not make sense.
The difference between the two, as elclanrs says, is all about the .
. Let's say I made my own object phew = {baz: 44}
. I could, validly, "steal" a method from foo
like this: phew.myMethod = foo.bar
. Now, phew
knows the instructions contained in bar
, and if I call phew.myMethod()
, I would get 44 as my result because phew
is calling the method, and phew
's baz
is 44; it doesn't matter where the method is defined! All that matters is what the method says to do, and bar
says to return the baz
of whoever called it.
So now, going back to your code, you're calling arguments[0]()
. It does seem like it should be the same, but because functions are first-class objects, when you passed it as a parameter, all you really passed was a function called bar
. When you called arguments[0]()
, it was like calling bar()
, which is different from calling foo.bar()
just like it's different from calling phew.myMethod()
, even though they all are exactly the same function.
For more info, try this SO post