It is a special object in JavaScript that refers to an object it belongs to. The value of this
is decided at the moment of code execution.
How do you know what this
refers to? It's simple, take a look at the following rules:
window
:console.log(this); // Prints "Window"
function
it refers to the global object as well:function example() {
console.log(this);
};
example(); // Prints "Window" if executed in browser
function
in strict mode, the value of it is undefined
:Strict Mode was a new feature in ECMAScript 5 that allows you to place a program, or a function, in a “strict” operating context. This strict context prevents certain actions from being taken and throws more exceptions. The statement
"use strict"
instructs the browser to use the strict mode, which is a reduced and safer feature set of JavaScript.
"use strict";
console.log(this); // Prints "undefined"
function example() {
console.log(this);
};
example(); // Prints "undefined"
function handleClick(e) {
console.log(this); // Refers to the "button" element
};
<button onclick="handleClick">
Click me
</button>
const person = {
name: "John",
surname: "Doe",
getFullName: function() {
console.log(this); // Refers to "person" object
},
};
person.getFullName();
call
and apply
can bind it to any object:const john = {
name: "John",
surname: "Doe",
getFullName: function() {
return this.name + " " + this.surname;
},
};
const andrew = {
name: "Andrew",
surname: "Hopkins",
};
john.getFullName.call(andrew); // Prints "Adrew Hopkins"
john.getFullName.apply(andrew); // Prints "Adrew Hopkins"
bind
function can bind it to any object:
The reason, why we haven't included bind to the previous point is because bind returns a new function which can be called later with passed context. In case of call or apply, the function gets invoked immediately.
const fullName = john.getFullName.bind(andrew); // Prints nothing, has to be invoked
fullName(); // Prints "Adrew Hopkins", it remembers passed context
const example = () => {
console.log(this);
};
example(); // Prints "Window" in browser
function parent() {
const child = () => {
console.log(this);
};
child();
};
parent(); // Still prints "Window" in browser
Tricky examples:
const john = {
name: "John",
surname: "Doe",
getFullName: function() {
const lowerCaseFullName = () => {
// This refers to "john" object
return this.name.toLowerCase() + " " + this.surname.toLowerCase();
};
return lowerCaseFullName();
},
};
john.getFullName(); // Prints "john doe"
In the example above since we're using function declaration, this
is bound to the john
object:
const john = {
name: "John",
surname: "Doe",
getFullName: () => {
const lowerCaseFullName = () => {
return this.name.toLowerCase() + " " + this.surname.toLowerCase();
};
return lowerCaseFullName();
},
};
john.getFullName(); // TypeError: Cannot read property "name" of undefined
In this example, this
is bound to the global object since getFullName
is a fat arrow function.
Using this
keyword is a very tricky topic in JavaScript.
Make sure to learn these simple rules and use them wisely to know which object this
refers to in your code:
window
undefined
call
, apply
and bind
can bind it to any object