To know a programming language doesn’t mean that you understand it or are using it properly. It’s the same with JavaScript. Although it’s an easy language to learn, there are many pitfalls for novices, and even for seasoned programmers.
One thing that confuses inexperienced developers is how the this
keyword works. Put simply, this
is a referencing alias—it’s just knowing what exactly it references, that is the tricky part.
This article aims to dispel the confusion and offer an insight into the inner workings of the this
keyword.
Key Takeaways
- “this” in JavaScript is a special identifier keyword that points to the “owner” of the function being executed. Its value is based on the context in which the function is called at run-time, not where the function is declared.
- The “this” keyword behaves differently in different contexts: in global scope it refers to the global object, in a simple function call it defaults to the global object, in an object’s method it’s set to the object the method is called on, and in constructor functions it’s bound to the newly constructed object.
- JavaScript provides built-in mechanisms for controlling the behavior of “this”. The apply() and call() methods can be used to explicitly set the value of “this”, and the bind() method can be used to bind a specific object to “this” when a function or method is invoked.
- Understanding the “this” keyword is crucial for using JavaScript properly and confidently. It’s a common pitfall for both novice and seasoned programmers due to its tricky nature.
So, What is this
Anyway?
In a nutshell, this
is a special identifier keyword—automatically defined in the scope of every function—pointing to the “owner” of the function being executed. But, to fully grasp its tricky nature, we need to answer two key questions:
How is this
Created?
Each time a JavaScript function is invoked, a new object is created containing information about which parameters were passed, how the function was invoked, where the function was called from, and so on. One of the main properties of that object is the this
reference, which is automatically bound to the object of which the function is a method.
Note: for the curious, this is detailed in §10.4.3 of the ECMAScript Language Specification and the sections which that links to.
var car = {
brand: "Nissan",
getBrand: function(){
console.log(this.brand);
}
};
car.getBrand();
// output: Nissan
JS Bin
In this example this
, used in this.brand
, is a reference to the car
object. So, this.brand
is the same as car.brand
.
What Does this
Refer to?
The value of this
, passed to all functions, is based on the context in which the function is called at run-time. The scope of this
isn’t concerned with how and where functions are declared, but rather where they are called from (i.e. the context).
Every line of JavaScript code is run in an execution context. The object that this
refers to is redefined every time a new execution context is entered and remains fixed until it’s shifted to a different context. To find the execution context (and this
binding) we need to find the call-site—the location in the code where a function is called from (not where it’s declared).
Let’s demonstrate this in the following example:
var brand = 'Nissan';
var myCar = {brand: 'Honda'};
var getBrand = function() {
console.log(this.brand);
};
myCar.getBrand = getBrand;
myCar.getBrand();
// output: Honda
getBrand();
// output: Nissan
JS Bin
Even though both myCar.getBrand()
and getBrand()
point to one and the same function, the value of this
is different because it’s based on the context in which getBrand()
is being called.
As we already know, within a function, this
is bound to the object of which the function is a method. In the first function call, the object is myCar
, while in the second, the object is window
(getBrand()
is the same as window.getBrand()
). So, a different context yields different a result.
Invocation Contexts
Now, let’s look at what this
points to when it’s put into different contexts.
Global Scope
All JavaScript runtimes have a unique object called the global object. In browsers, the global object is the window
object. In Node.js, it’s called the global
object.
In the global execution context (outside of any function), this
refers to the global object, whether in strict mode or not.
Local Scope
Inside of a function, the value of this
depends on how the function is called. There are three main variations:
this
Used in a Simple Function Call
The first variation is a standalone function invocation where we call a function directly.
function simpleCall(){
console.log(this);
}
simpleCall();
// output: the Window object
In this case, the value of this
is not set by the call. Since the code is not running in strict mode, the value of this
must always be an object so it defaults to the global object.
In strict mode, the value of this
remains at whatever it’s set to when entering the execution context. If it’s not defined, it remains undefined, as we can see in the following example:
function simpleCall(){
"use strict";
console.log(this);
}
simpleCall();
// output: undefined
this
Used in an Object’s Method
We can store a function in a property of an object, which turns it into a method that we can invoke via that object. When a function is called as a method of an object, its this
value is set to the object the method is called on.
var message = {
content: "I'm a JavaScript Ninja!",
showContent: function() {
console.log(this.content);
}
};
message.showContent(); // output: I'm a JavaScript Ninja!
JS Bin
Here, showContent()
is a method of the message
object, and thus this.content
is equal to message.content
.
this
Used in Constructor Functions
We can invoke a function via the new
operator. In this case the function becomes a constructor—a factory for objects. Unlike the simple function calls and method calls discussed above, a constructor call passes a brand new object as the value of this
, and implicitly returns the new object as its result.
When a function is used as a constructor (with the new
keyword), its this
value is bound to the newly constructed object. If we miss the new
keyword, then it will be a regular function and this
will point to the window
object.
function Message(content){
this.content = content;
this.showContent = function(){
console.log(this.content);
};
}
var message = new Message("I'm JavaScript Ninja!");
message.showContent();
// output: I'm JavaScript Ninja!
JS Bin
In the above example, we have a constructor function named Message()
. By using the new
operator we create a brand new object named message
. We also pass the constructor function a string, which it sets as the content
property of our new object. In last line of code we see that this string is successfully output, because this
is pointing to the newly created object, and not to the constructor function itself.
How this
Can Be Successfully Manipulated
In this section, we’ll examine some built-in mechanisms for controlling the behavior of this
.
In JavaScript, all functions are objects, and therefore they can have methods. Two of these methods, which all functions have, are apply() and call(). We can use these methods to change the context to whatever we need and thus, explicitly set the value of this
.
The apply()
method takes two arguments: an object to set this
to, and an (optional) array of arguments to pass to the function.
The call()
method works exactly the same as apply()
, but we pass the arguments individually rather than in an array.
Let’s see it in action:
function warrior(speed, strength){
console.log(
"Warrior: " + this.kind +
", weapon: " + this.weapon +
", speed: " + speed +
", strength: " + strength
);
}
var warrior1 = {
kind: "ninja",
weapon: "shuriken"
};
var warrior2 = {
kind: "samurai",
weapon: "katana"
};
warrior.call(warrior1, 9, 5);
// output: Warrior: ninja, weapon: shuriken, speed: 9, strength: 5
warrior.apply(warrior2, [6, 10]);
// output: Warrior: samurai, weapon: katana, speed: 6, strength: 10
JS Bin
Here, we have a factory function warrior()
, which is used to create different types of warriors by using different warrior objects. So, in that factory function, this
will point to the different objects we pass in using call()
and/or apply()
.
In the first function call, we use the call()
method to set this
to the warrior1
object, and pass the other arguments we need, separated by commas. In the second function call, we do almost the same, but this time we pass in the warrior2
object and the necessary arguments are put in an array.
Besides apply()
and call()
ECMAScript 5 added the bind() method, which also allows us to set which specific object will be bound to this
when a function or method is invoked. Let’s consider the following example:
function warrior(kind){
console.log(
"Warrior: " + kind +
". Favorite weapon: " + this.weapon +
". Main mission: " + this.mission
);
}
var attributes = {
weapon: "shuriken",
mission: "espionage"
};
var ninja = warrior.bind(attributes, "ninja");
ninja();
// output: Warrior: ninja. Favorite weapon: shuriken. Main mission: espionage
JS Bin
In this example, the bind()
method is used in similar way, but unlike the call()
and apply()
methods, warrior.bind()
creates a new function (with the same body and scope as warrior()
) rather than modifying the original warrior()
function. The new function behaves just like the old one, but with its receiver bound to the attributes
object, while the old one remains unchanged.
Summary
So, that’s it. This is almost everything you need to know about the this
keyword in order to use it properly and with more confidence. Of course, there are some tricky parts and some common issues which you may face up along the way. These will be explored in an upcoming article, so stay tuned.
Frequently Asked Questions about JavaScript’s ‘this’ Keyword
What is the ‘this’ keyword in JavaScript and how does it work?
The ‘this’ keyword in JavaScript is a special keyword that refers to the context in which a function is called. It’s a reference to the object that invoked the function. The value of ‘this’ is determined by how a function is called, not where it is defined or called. It can be a bit tricky to understand because its value can change depending on the context.
How does ‘this’ behave in global scope?
In the global scope, ‘this’ refers to the global object. In a browser, the global object is the window object. So, if you use ‘this’ in the global scope or inside a function that is not a method or a constructor, ‘this’ will refer to the window object.
How does ‘this’ behave inside a method?
Inside a method, ‘this’ refers to the object that the method belongs to. For example, if you have an object with a method, and you call that method, ‘this’ will refer to the object. This is useful for accessing other properties or methods of the same object.
How does ‘this’ behave inside a constructor?
Inside a constructor function, ‘this’ refers to the newly created object. A constructor function is a special kind of function that is used to create new objects with the same properties and methods.
How does ‘this’ behave inside an event handler?
Inside an event handler, ‘this’ refers to the HTML element that received the event. This is useful for manipulating the element in response to user actions.
What is the difference between ‘this’ and ‘self’ in JavaScript?
this’ and ‘self’ are both used to refer to the object that the current code is operating on. However, ‘self’ is not a keyword in JavaScript, it’s just a common name for a variable that is used to hold a reference to an object. The value of ‘self’ is not automatically set by JavaScript, you have to set it yourself.
How can I change the value of ‘this’ in a function?
You can change the value of ‘this’ in a function using the call(), apply(), or bind() methods. These methods allow you to specify the object that should be used as ‘this’ when calling a function.
What is ‘use strict’ and how does it affect ‘this’?
use strict’ is a directive that enables strict mode in JavaScript. In strict mode, ‘this’ inside a function that is not a method or a constructor is undefined, instead of referring to the global object. This can help prevent common mistakes.
What is arrow function and how does it affect ‘this’?
Arrow functions are a new feature in ES6 that provide a more concise syntax for writing functions. One important difference between arrow functions and regular functions is that ‘this’ inside an arrow function is lexically bound. This means it retains the value of ‘this’ from its enclosing context, instead of being set based on how the function is called.
What are some common mistakes when using ‘this’ in JavaScript?
Some common mistakes when using ‘this’ in JavaScript include assuming that ‘this’ inside a function always refers to the function itself, or that ‘this’ inside a nested function refers to the same object as ‘this’ in the outer function. Another common mistake is not realizing that ‘this’ can be changed by call(), apply(), or bind().
I am a web developer/designer from Bulgaria. My favorite web technologies include SVG, HTML, CSS, Tailwind, JavaScript, Node, Vue, and React. When I'm not programming the Web, I love to program my own reality ;)