Skip to main content

How to Determine this

To determine this, you need to learn only one rule: the context value inside a function (not arrow) is determined not at the time of its creation, but at the time of calling. That is, the value of this is determined by how the function is called, not where it was declared.

this in the global scope

In the global scope, if the script is not executed in strict mode, this refers to the window object. In strict mode the value of this in the global scope will be undefined.

function foo() {
console.log(this);
}

foo(); // window without "use strict" and undefined with "use strict"

this in object method

If a function is called as an object method, the context will refer to the object that includes the method.

const petya = {
username: "Petya",
showThis() {
console.log(this);
},
showName() {
console.log(this.username);
},
};

petya.showThis(); // {username: "Petya", showThis: ƒ, showName: ƒ}
petya.showName(); // 'Petya'

Let's look at a more complex example for better understanding.

  • First, create a function in the global scope and call it.
  • Then assign it to an object property and invoke it as a method of this object.
function showThis() {
console.log("this in showThis: ", this);
}

// Calling in the global context
showThis(); // this in showThis: Window

const user = {
username: "Mango",
};

// Writing a reference to the function to the object property
// Note that this is not a call because it has no ()
user.showContext = showThis;

// Calling the function in the object context
// this will point to the current object that serves as the
// call context, not to the global object.
user.showContext(); // this in showThis: {username: "Mango", showContext: ƒ}

this in callback functions

When passing object methods as callback functions, the context is not preserved. A callback is a method reference that is assigned as the value of a parameter called without an object.

const customer = {
firstName: "Jacob",
lastName: "Mercer",
getFullName() {
return `${this.firstName} ${this.lastName}`;
},
};

function makeMessage(callback) {
// callback() is a call of the getFullName method without an object
console.log(`Processing request from ${callback()}.`);
}

makeMessage(customer.getFullName); // Function call error
Note

The solution to this problem is discussed in the section on bind() method and object methods.

this in arrow functions

Arrow functions do not have their own this. Unlike with regular functions, you cannot change the value of this inside an arrow after its declaration.

Note

The context inside an arrow is determined by the place of its declaration, not the call, and refers to the parent function’s context.

Arrow functions also ignore the presence of strict mode. If the arrow remembers the global context, this in it will contain a reference to window, regardless of whether the script is executed in strict mode or not.

const showThis = () => {
console.log("this in showThis: ", this);
};

showThis(); // this in showThis: window

const user = {
username: "Mango",
};
user.showContext = showThis;

user.showContext(); // this in showThis: window

By limiting arrow functions to a constant context, JavaScript engines can better optimize them, unlike regular functions whose this value can be changed.

The example is not practical, but it shows well how the context for arrows works. The context value is taken from the parent scope.

const hotel = {
username: "Resort hotel",
showThis() {
const foo = () => {
// Arrows remember the context during declaration,
// from the parent scope
console.log("this in foo: ", this);
};

foo();
console.log("this in showThis: ", this);
},
};

hotel.showThis();
// this in foo: {username: 'Resort hotel', showThis: ƒ}
// this in showThis: {username: 'Resort hotel',showThis: ƒ}