Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript Function Context Incorrect

Tags:

javascript

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?

like image 845
Amit Joki Avatar asked Jun 02 '15 11:06

Amit Joki


People also ask

What is function context in JavaScript?

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.

How do you not lose context?

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.

What does losing context mean?

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.

How can you call a function and assign the this context to an object?

call() and . apply() methods allow you to set the context for a function.


1 Answers

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?

like image 171
deceze Avatar answered Sep 19 '22 15:09

deceze