JavaScript Function Context Incorrect
Context in Javascript is always established by the way you call a function.
var fn = ''.toUpperCase.call
This assigns the prototype implementation of the call
function to fn
. If you now call fn()
, there's no context to the call. call
would try to invoke the function object it was associated with. However, that context is established at call time. Since you're not giving it any context at call time, some internal component of call
is throwing an error.
You'd have to do this:
fn.call(''.toUpperCase)
That's right, you call
the call
function, establishing a context, namely the toUpperCase
string function. In this specific case this would lead to another error inside toUpperCase
, since it is not bound to a specific context. You'd need to establish that context explicitly as well:
var fn = ''.toUpperCase.call
fn.call(''.toUpperCase.bind(''))
Also see How does the "this" keyword work?
deceze's answer is correct, I just want to explain it from a different point of view.
Your fn
is a reference to Function.prototype.call
which needs to be called with a function as its this
reference, in this case, the context for call
is String.prototype.toUpperCase
, which was inherited through ''.toUpperCase
On top of that, String.prototype.toUpperCase
also has to be called with a specific context, the string to upper case.
Here's another way to code what you wanted that may help you understand what is going on.
var str = 'aaa';
var upper = ''.toUpperCase;
var fn = upper.call;
// Now we have to specify the context for both upper and fn
console.log( fn.call(function() { return upper.call(str)}) ); // AAA
In your example, fn()
is attempting to call call
but it's not specifying the context, which typically defaults to the window
object but in this case it just makes it undefined
, which triggers a weird error in Chrome (as you discovered), but Firefox is clearer about the problem,
TypeError: Function.prototype.call called on incompatible undefined
So, when is a function, not a function?
The function is a function, but you are not executing it correctly, as explained in comments and the answer by @deceze
I noticed a weird thing in javascript.
You seem confused by the message that you are getting in the environment in which you tested, the message is not strictly correct.
Uncaught TypeError:
fn
is not a function
The current stable version of chromium (40.0.2214.91 on my linux install, chrome fails to run on my hardware without making settings changes), chrome being the environment on which you tested, gives a seemingly more correct error message that makes more sense.
Uncaught TypeError: undefined is not a function
So, were you asking/wanting to ask a serious question or were you just poking a little fun at a mistake in a version of chrome?