this
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
The this keyword refers to the context where a piece of code, such as a function's body, is supposed to run. Most typically, it is used in object methods, where this refers to the object that the method is attached to, thus allowing the same method to be reused on different objects.
The value of this in JavaScript depends on how a function is invoked (runtime binding), not how it is defined. When a regular function is invoked as a method of an object (obj.method()), this points to that object. When invoked as a standalone function (not attached to an object: func()), this typically refers to the global object (in non-strict mode) or undefined (in strict mode). The Function.prototype.bind() method can create a function whose this binding doesn't change, and methods Function.prototype.apply() and Function.prototype.call() can also set the this value for a particular call.
Arrow functions differ in their handling of this: they inherit this from the parent scope at the time they are defined. This behavior makes arrow functions particularly useful for callbacks and preserving context. However, arrow functions do not have their own this binding. Therefore, their this value cannot be set by bind(), apply() or call() methods, nor does it point to the current object in object methods.
Try it
const test = {
prop: 42,
func() {
return this.prop;
},
};
console.log(test.func());
// Expected output: 42
Syntax
this
Value
In non–strict mode, this is always a reference to an object. In strict mode, it can be any value. For more information on how the value is determined, see the description below.
Description
The value of this depends on in which context it appears: function, class, or global.
Function context
Inside a function, the value of this depends on how the function is called. Think about this as a hidden parameter of a function — just like the parameters declared in the function definition, this is a binding that the language creates for you when the function body is evaluated.
For a regular function (not an arrow function, bound function, etc.), the value of this is the object that the function is accessed on. In other words, if the function call is in the form obj.f(), then this refers to obj. For example:
function getThis() {
return this;
}
const obj1 = { name: "obj1" };
const obj2 = { name: "obj2" };
obj1.getThis = getThis;
obj2.getThis = getThis;
console.log(obj1.getThis()); // { name: 'obj1', getThis: [Function: getThis] }
console.log(obj2.getThis()); // { name: 'obj2', getThis: [Function: getThis] }
Note how the function is the same, but based on how it's invoked, the value of this is different. This is analogous to how function parameters work.
The value of this is not the object that has the function as an own property, but the object that is used to call the function. You can prove this by calling a method of an object up in the prototype chain.
const obj3 = {
__proto__: obj1,
name: "obj3",
};
console.log(obj3.getThis()); // { name: 'obj3' }
The value of this always changes based on how a function is called, even when the function was defined on an object at creation:
const obj4 = {
name: "obj4",
getThis() {
return this;
},
};
const obj5 = { name: "obj5" };
obj5.getThis = obj4.getThis;
console.log(obj5.getThis()); // { name: 'obj5', getThis: [Function: getThis] }
If the value that the method is accessed on is a primitive, this will be a primitive value as well — but only if the function is in strict mode.
function getThisStrict() {
"use strict"; // Enter strict mode
return this;
}
// Only for demonstration — you should not mutate built-in prototypes
Number.prototype.getThisStrict = getThisStrict;
console.log(typeof (1).getThisStrict()); // "number"
If the function is called without being accessed on anything, this will be undefined — but only if the function is in strict mode.
console.log(typeof getThisStrict()); // "undefined"
In non-strict mode, a special process called this substitution ensures that the value of this is always an object. This means:
- If a function is called with
thisset toundefinedornull,thisgets substituted withglobalThis. - If the function is called with
thisset to a primitive value,thisgets substituted with the primitive value's wrapper object.
function getThis() {
return this;
}
// Only for demonstration — you should not mutate built-in prototypes
Number.prototype.getThis = getThis;
console.log(typeof (1).getThis()); // "object"
console.log(getThis() === globalThis); // true
In typical function calls, this is implicitly passed like a parameter through the function's prefix (the part before the dot). You can also explicitly set the value of this using the Function.prototype.call(), Function.prototype.apply(), or Reflect.apply() methods. Using Function.prototype.bind(), you can create a new function with a specific value of this that doesn't change regardless of how the function is called. When using these methods, the this substitution rules above still apply if the function is non-strict.
Callbacks
When a function is passed as a callback, the value of this depends on how the callback is called, which is determined by the implementor of the API. Callbacks are typically called with a this value of undefined (calling it directly without attaching it to any object), which means if the function is non–strict, the value of this is the global object (globalThis). This is the case for iterative array methods, the Promise() constructor, etc.
function logThis() {
"use strict";
console.log(this);
}
[1, 2, 3].forEach(logThis); // undefined, undefined, undefined
Some APIs allow you to set a this value for invocations of the callback. For example, all iterative array methods and related ones like Set.prototype.forEach() accept an optional thisArg parameter.
[1, 2, 3].forEach(logThis, { name: "obj" });
// { name: 'obj' }, { name: 'obj' }, { name: 'obj' }
Occasionally, a callback is called with a this value other than