I noticed a weird thing in javascript. Consider the below:
var fn = ''.toUpperCase.call
console.log(typeof fn); // "function"
fn(); // Uncaught TypeError: `fn` is not a function
The above was executed on my Chrome's Developer Console. Version is 43.0.2357.81 m
.
The typeof
operator clearly shows that fn
is a function, but the error suggests otherwise.
I've noticed that Function.apply
shows at least some meaningful error message.
So, when is a function, not a function?
What is context? Context is always the value of the this keyword which is a reference to the object that “owns” the currently executing code or the function where it's looked at. We know that window is a global object in the browser so if we type this in the console and it should return window object, which it does.
The best way to avoid this losing context is to not use this at all. However, this is not always an option. We may have inherited code that uses this or we might work with a library making use of this . Object literals, constructor functions, and class es build objects over the prototype system.
Meaning loss, meanwhile, refers to the loss of emotional and social significance of shared content. Finally, context loss refers to a lack of understanding of the conversation's flow.
call() and . apply() methods allow you to set the context for a function.
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With