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?