Understanding Javascript ‘this’ keyword (Context)
-
Context is one of those topics that always creates a lot of confusion when someone is starting to learn javascript and it’s a topic that the interviewer asks about a lot
OK! Let's Start ...
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 typethis
in the console and it should return window object, which it does.Context — globally and inside a function.
foo
is the function is defined at the global level and is called on global level object i.ewindow
so callingfoo
andwindow.foo
is same. Hence the context is awindow
object.Whereas if we do
new foo()
at the global level then will getthis
as fooobject.Context — under 2nd level function
Context — when the function is defined globally and used under an object (Implicit Binding).
When using
use strict
in a function, the context i.e this keyword behaves differently. Context remains whatever it was called upon.How context behave in arrow function?
Arrow functions work differently from regular functions in terms of context. `this` will always refer to the lexical scope (read here about scope), i.e `this` retains the value of the enclosing lexical context's.In global code, it will be set to the global object, hence we get above true.
How does context behave on the object’s prototype chain?
Context follows the same rule, i.e. if the function is on an object’s prototype chain,
this
refers to the object the method was called on.If we call
obj.func()
will getundefined
and iffunc
is called onnewObj
created fromobj
which hasx
defined it will return the value hence 10.How context behave in the event handlers?
The context in case event handlers refers to the element that received the event.Here we added a jquery click event on body tag of DOM, and we can see that the context returns the body element.
How does the context behave in an execution context?
If you don’t know what is execution context. In short, execution context is the ‘environment’ or scope in which a function executes in. Every time a function is called, a new
execution context
is created. Every call to anexecution context
has 2 stages- Creation — when the function is called
- Activation — when the function is executed
The value of
this
is determined at creation phase, not at the time of execution. However,this
determination rule remains the same.How is context is different from the scope?
Scope and context are altogether a different concept but usually used by the upcoming developer interchangeably.
The scope is the accessibility of variables, functions, or objects in some particular part of your code during runtime
Every function invocation has both a scope and a context associated with it.
How to explicitly change the context?
We can dynamically change the context of any method by using either
call()
,apply()
andbind()
method.Call — The very first argument
call
takes in is the context you want to use. Afterward, you can pass in any number of comma-separated values.foo.call(context, param1, param2, param3 );
Apply — This is the same as
call
but differs in the sense of no. of argument. Apply only support 2 arguments, context and array of values.foo.apply( context,[param1, param2, param3]);
Bind — It returns a new function which is permanently bound to the first argument of
bind
regardless of how the function is being used.bind
doesn’t invoke the bound function immediately, rather it returns a new function we can run later.Why do we need to explicitly change the context?
-
When we need to call a function defined inside an object say xbut on other objects say ywe can use explicit methods to do so, to increase reusability.
-
Currying and partial application is another part where explicitly change in context is used.
-
To make utility functions like
- Inheritance is another place where the explicit change of context can be used.
What are the cases where we need to take care of context?
We may lose the context i.e getting an
undefined
value forthis
in- Nested Functions
We need to keep the context of the
obj
object referenced for when the callback function is called, in the above, that does not happen and we get the error.We can get rid of the above error by replacing the
exec
code with below:// use of bind exec: function () { this.f2(function () { this.f1(); }.bind(this)); } // use of arrow function exec: function () { this.f2(() => { this.f1(); }); } // another way not recommended though exec: function () { var that = this; this.f2(() => { that.f1(); }); }
src: https://towardsdatascience.com/javascript-context-this-keyword-9a78a19d5786