‘this’ in Javascript

Objects are the basic building blocks in JavaScript. There’s one special object available in JavaScript, the this
object. You can see the value of this
at every line of JavaScript execution. The value of this
is decided based on how the code is being executed.
Before getting started with this
, we need to understand a little about the JavaScript runtime environment and how a JavaScript code is executed.
Scope vs Context
When approaching this
for the first time, many developers presume that it works in a similar way to scope. But that thinking can lead to mistakes!
That’s because `this
` depends on context, rather than scope…so what’s the difference?
What is Scope?
Scope controls the context in which variables are accessible. Here’s a classic example:
function foo() {
const bar = true;
return bar;
};
console.log(foo()); // true
console.log(bar); // ReferenceError: bar is not defined
The variable bar
is only accessible inside our function, foo
. If we call foo()
, we’ll get the value of bar
. But if we try to use bar
outside of foo
, we’ll get a ReferenceError
. This is known as local scope or functional scope.
It’s tempting to imagine that this
works in the same way. But this misunderstanding is probably the reason for most beginners’ mistakes!
What is Context?
To get an understanding of context, let’s re-write our function foo
to set the value of this.bar
:
function foo() {
this.bar = true;
return bar;
};
console.log(foo()); // true
console.log(bar); // true
Beginners often assume that, in the above example, this
refers to the function foo
. But when we try to access bar
, we can!
That’s because the expression
this.bar = true
is actually writing a global variablebar
. That’s because we haven’t set a specific context and so, as in the first example in this article,this
refers to the global object. To givethis
a context, you need to use a method likecall
,apply
orbind
.
Thus, the object this
refers to changes every time the execution context is changed.
`this` refresher
In Object Oriented JS we learned that in JS, everything is an object. Because everything is an object, we came to understand that we could set and access additional properties to functions.
Setting properties to a function and additional methods via the prototype is super awesome … but how do we access them?!??!
We were introduced to the this
keyword. We learned that every function gets this property automatically.
But life isn’t perfect. Sometimes, we lose our this
reference. When that happens, we end up using confusing hacks to save our reference to this
. Check out this confusing hack from our localStorage exercise:

So, why did I need to save a this
reference? Because inside deleteBtn.addEventListener, this
refers to the deleteBtn object. This is unfortunate. Is there a better solution? YES….in such cases call(), apply() and bind() comes to the rescue.
“this” has different values depending on how is the function invoked instead of where is “this” taken from.
- In a method,
this
refers to the owner object. - Alone,
this
refers to the global object. - In strict mode, when used alone,
this
also refers to the Global object[object Window]
"use strict";
var x = this; # [object Window]
- In a function,
this
refers to the global object. - In a function, in strict mode,
this
isundefined
. - In an event,
this
refers to the element that received the event. - Methods like
call()
, andapply()
can referthis
to any object.
In the example below, when calling person1.fullName with person2 as argument, this
will refer to person2, even if it is a method of person1:
var person1 = {
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
var person2 = {
firstName:"John",
lastName: "Doe",
}
person1.fullName.call(person2); // Will return "John Doe"

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.
In node.js CLI if you try doing the above you will get an object that will have all globally used function like console
, process
etc. (try once).
Note: The value of
this
keyword depends on the object the function is run/called /sit on. Thereforethis
keyword has different values depending on where it is used.Note: From now, this and context is used interchangeably.
[1].Context — globally and inside a function.

foo
is the function is defined at the global level and is called on global level object i.e window
so calling foo
and window.foo
is same. Hence the context is a window
object.
Whereas if we do new foo()
at the global level then will get this
as foo
object, as below:

Note: new
operator creates an instance of an object. Context of the function will be set to the created instance of an object.
[2].Context — under 2nd level function.

[3]. Context — when the function is defined globally and used under an object (Implicit Binding).

Note: From above, we get that value of this
keyword depends on the function is called upon not where the function is defined.
source: https://medium.com/@happymishra66/this-in-javascript-8e8d4cd3930
In most cases, the value of this is determined by how a function is called. It can’t be set by assignment during execution, and it may be different each time the function is called. You can change this context through .call(), .apply() and .bind(). Value of this is equal to the value of the object which invokes the function. this is not assigned a value until an object invokes the function where this is defined.
Global Context
When functions are executed in the global scope, value of this is window object. This is because when we call a function in global scope by default they are invoked on the Window object. In strict mode, value of this in the global context will be undefined. Consider the below example:
var myFunction = function(){
console.log(this);
console.log(this=== window);
}
myFunction();
// Output: Window object. In strict mode value will be undefined

The above function was not executed inside any other function or object hence, by default myFunction was called on the global object.
myFunction() is equivalent to window.myFuntion()
Hence the value of this is ‘window’. In strict mode, value of this would be undefined.

As an object method
When a function is called as a method of an object, it’s this is set to the object the method is called on.
Example:
var val = 37;
var myObj = {
val : 10,
someFunction : function(){
console.log(this.val);
//Output: 10 since the value of this is equal to myObj
console.log(window.val); //Output: 37
console.log(this === myObj) // true
console.log(this)//Output: myObj object
}
}
myObj.someFunction();

In the above example, we have defined two val variables, one in the global scope with value 37 and another inside myObj object with value 10.
When we call myObj.someFunction(), as someFunction() was called by myObj object, value of this inside someFunction will become equal to myObj.
Hence, inside someFunction when we do console.log(this.val), it outputs myObj’s val variable value i.e 10.
When we do window.val, we get value 37 as global value for val is 37.
Another example:
//Variable defined in global scope
var val = 37;
var myObj = {
val : 10
}
var someFunction = function(){
console.log(this.val);
console.log(window.val);
console.log(this === myObj);
console.log(this);
console.log(this === window)
}
myObj.objectFunc = someFunction;
myObj.objectFunc();
/*
Output:
1. 10
2. 37
3. true
4. myObj
5. false
*/
someFunction();
/*
Output:
1. 37
2. 37
3. false
4. window
5. true
*/
In the above example, we have defined someFunction outside myObj object.
First we call someFunction() on myObj object, hence inside someFunction value of this is equal to myObj object.
In second case, we have called someFunction() in the global scope which is same as writing window.someFunction(). Here, as someFunction() has been called on window object, value of this is equal to window object.
First we call someFunction() in the context of myObj. Later we called the function in the global context and the value of this inside the someFunction() changed accordingly. This shows that the value of this was determined dynamically on the basis of execution context.
As a constructor
When a function is used as a constructor (with the new keyword), its this is bound to the new object being constructed. To understand what constructor function are, please go through this article.
function ConstructorFunc(value){
this.someValue = value;
}
var obj1 = new ConstructorFunction(20);
console.log(obj1.someValue)//Output: 20

Here, we have defined ConstructorFunc to create new objects. When
var obj1 = new ConstructorFunction(20) is executed, value of this will be equal to the new object that is created.
◉ ‘this’ inside an IIFE
In IIFE, value of this is always equal to Window object. Why?
As, IIFE is self-invoked, it has not been called by any object. Hence, the value of this inside IIFE is Window object.
Let’s see an example:
// IIFE outside any function
(function() {
console.log(this); // Output: Window object
})()
// IIFE inside an object function
var obj = {};
var someFunc = function() {
console.log("Functions this");
console.log(this === obj); // true
console.log('++++++++++++++++++++++++++');
// IIFE
(function() {
console.log("IIFE this");
console.log(this); // Output: Window object
console.log("IIFE");
})()
};
obj.func = someFunc;
obj.func();
Console Output:
First example:

In the first example, IIFE outside any function, value of this inside IIFE will be Window object.
Second Example:

In the second example, when we have called IIFE inside someFunc still the value of this is Window object not obj object.
This is because, value of this inside a function is equal to the object on which it is called. someFunc is called on obj, hence value of this inside someFunc is obj. But, IIFE is self-invoked, it has not been called by any object. Hence, the value of this inside IIFE is Window object.
Event handler in JavaScript
Inside event handler, value of this is equal to the element on which the event is fired. Let’s see this with an example of click event.
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="divId">Hello</div>
<script type="text/javascript">
var id = document.getElementById('divId').addEventListener('click', clickMe, false);
function clickMe(event) {
console.log(event.currentTarget);
console.log("CLick Me");
console.log(this);
}
</script>
</body>
</html>
In the above example, we have added an on click event handler on the div element which calls the clickMe function.

When we click on the div, from the above console output we can see that value of this is equal to the div element which we clicked.
We can change the value of this at run time using call, apply and bind function. We will discuss call, apply and bind in another article.
◉ “this” inside arrow functions
this.robot = "global";
const thisRobots = {
robot: "local_1", anotherRobotName: function (robot = "new_local") {
return this.robot;
}, details: {
robot: "local_2",
robotName: function () {
return this.robot;
}, arrowrobotName: () => this.robot
}
};console.log(thisRobots.details.robotName());
console.log(thisRobots.details.arrowrobotName());
console.log(thisRobots.anotherRobotName());# local_2
# global
# local_1
Examples:
const func = () => { return this };
let obj = {func, a: 10}
obj.func(); # window
We will always get the global window
object here coz of arrow functions.
'this’
cannot be changed by usingcall
,apply
orbind
. If you need to change a binding, use a regular function.
const a = () => {
return this;
}
a() === window;
# true
source: youtube/techsith
◉ “this” in global scope
this.name = "RSSB";
console.log(window.name); # anil// this is a public property of window means accessible from outsidethis.name = {
firstname: "anil"
}
this.name.firstname; # anil
OR
window.name.firstname; # anil
◉ “this” inside node.js
Not every JavaScript program runs in a browser. You should be aware that, in non-windowed environments, the global meaning of this
won’t be the window
object — because this
doesn’t exist!
Note that, when used globally in Node.js, this
represents an empty object:
console.log(this); // {}
this.foo = 'bar' ;
console.log(this); // { foo: 'bar' }
◉ `this` inside an object
let name = {
firstname: "anil"
}name.firstname; # anil
this.name.firstname; # TypeError: cannot read property of undefined
◉ `this` inside a method
let name = {
firstname: "anil",
getFullName: function(){
return this.firstname;
}
};
console.log(name.getFullName()); # anil
◉ `this` inside a function (outside of an object):
this.name = "RSSB";
const getFullName= function(){
return this.firstname;
}getFullName();
# RSSB~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"use strict"
this.name = "RSSB";
const getFullName= function(){
return this.firstname;
}getFullName();
# undefined
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"call" to the rescue for above"use strict";
this.name = "RSSB";
const getFullName= function(arg){
return this.firstname + arg;
}getFullName.call(this, "to all"); # RSSB to all
◉ `this` inside a nested function
◉ `this` inside classes
Using Bind in Class Methods
If you’re used to a framework like React, which makes heavy use of JavaScript classes, you’ll likely be used to binding your methods inside your class’s constructor
method:
import React from 'react'; class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
this.addOne = this.addOne.bind(this);
}; addOne(event){
this.setState({ count: this.state.count + 1 });
};
render(){
return (
<button type="button" onClick={this.addOne}>
Click Me
</button>
);
};
};
The reason for the longwinded expression this.addOne = this.addOne.bind(this)
is that we always want the addOne
method to be executed in the context of the current React class. Otherwise, our value of this
will not be what we expect.
React classes run in ‘strict mode’, so instead of
this
defaulting towindow
, it returnsundefined
: ouraddOne
method would attempt to useundefined.setState
, which — of course — doesn’t exist!
Using the bind
method means that, whenever we call addOne
, it will use the setState
method that is part of our class.
Implicit Binding with Arrow Functions
More experienced React developers might prefer to avoid writing out the bind
expression with every new method. Instead, the Counter
component above could be re-written like so:
import React from 'react';class Counter extends React.Component {
state = { count: 0 }; addOne = (event) => {
this.setState({ count: this.state.count + 1 });
};
render(){
return (
<button type="button" onClick={this.addOne}>
Click Me
</button>
);
};
};
This works because the arrow function automatically adopts the this
binding from the enclosing scope — in this class, Counter
.
JavaScript ‘this’ in Regular, Arrow functions and Methods — a Short Circuit Example
To start, it is worth noting how outside of any function this
points to what is referred as the global object. Consider this example:
this.robot = "Hal 9000";
Try console.log(this.robot)
what you get? `Hall 9000` of course.
MDN Documentation explains how this
can be determined by where and how a function is called. There are nuances in strict mode but we will omit them for brevity of this article. With that in mind, lets consider this function:
function robotName(){
console.log(this.robot)
}
Calling robotName() will give you an error? Well not really, it will give you Hall 9000 again. Why? Because in a regular function context, this
defaults to the global object (unless we specify otherwise).
Let’s do that:
function robotName() {
this.robot = "Astro Boy";
console.log(this.robot)
}
// => Astro Boy
So when we call robotName(), what do we get? Astro Boy!
Let’s get make things a bit more complex. Consider this:
thisRobots.details.robotName();
# Astro Boy
robotName()
is in the context of the details object. Now, what if we called
thisRobots.details.arrowrobotName();
# Hall 9000
Surprised? Well this is a main distinction of arrow functions vs regular functions is that in arrow functions `this
will retain the value of its enclosing context. Since it will be determined by its surrounding scope, in our case, is the global context, so again `this` will be the territory of Hall 9000. this
in arrow functions is always inherited from their surrounded scope, it doesn’t have scope of its own like regular functions.
thisRobots.anotherRobotName(); # calling without arguments
# Johnny 5!
Why?? Well anotherRobotName()
method is defined inside thisRobots
which is an object.
When we call a method in an object, this
is bound to its surrounding object, in this case thisRobots
object.
◉ `this` exercises
function func() {
return this;
};
func(); # global window object# But there are three methods we can use to change the meaning of this when we call it: call , apply and bind .# Say we wanted this to represent the string 'Hello World!' , we can do that in a number of ways:func.call('Hello World');
func.apply('Hello World');
func.bind('Hello World')();# Each line of the code above would return the string 'Hello World!'const a = 1;
const obj = { a: 2 };
function whatIsA() { return this.a };
Whether whatIsA()
returns 1
or 2
will depend on how we call it:
whatIsA(); // 1
whatIsA(obj); // 1
whatIsA.call(obj); // 2
whatIsA.apply(obj); // 2
whatIsA.bind(obj)(); // 2var x = "global";
const foo= {
x: 10,
getX: function () {
return this.x;
}
};
let y = foo.getX;
console.log(y()); # global
If we call y
, what’s will the result be? Without any specific context, this
will take the value of x
in the global context. In this case, there isn’t one, so we’ll get undefined
.
But we can bind our function y
to the context of foo
:
const foo = {
x: 10,
getX: function () {
return this.x;
}
};
let y = foo.getX;
y = y.bind(foo); or y.bind(foo)();
Now, whenever we call y
, we’ll get the number 10
. Pretty useful!
References:
Must Reads @ https://medium.com/better-programming/understanding-the-this-keyword-in-javascript-cb76d4c7c5e8