Value of "this" Flashcards
What is this
?
In non–strict mode, this is always a reference to an object. In strict mode, it can be any value.
The value of this
depends on in which context it appears: function
, class
, or global
.
“What is “this”?” (MDN Web Docs). Retrieved November 14, 2023.
What is the value of this
on a function
context?
Inside a function, the value of this
depends on how the function is called. this
is a binding that the language creates for you when the function body is evaluated.
For a typical function, 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
.
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] }
Please note that 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] }
In strict mode:
- 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 beundefined
— 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
this
set toundefined
ornull
,this
gets substituted with globalThis. - If the function is called with
this
set to a primitive value, this gets substituted with the primitive value’s wrapper object.
“Function context” (MDN Web Docs). Retrieved November 14, 2023.
What is the value of this
on arrow functions?
In arrow functions, this
retains the value of the enclosing lexical context’s this
. In other words, when evaluating an arrow function’s body, the language does not create a new this
binding.
For example, in global code, this
is always globalThis
regardless of strictness, because of the global context binding:
const globalObject = this; const foo = () => this; console.log(foo() === globalObject); // true
Arrow functions create a closure over the this
value of its surrounding scope, which means arrow functions behave as if they are “auto-bound” — no matter how it’s invoked, this
is bound to what it was when the function was created (in the example above, the global object). The same applies to arrow functions created inside other functions: their this
remains that of the enclosing lexical context.
Furthermore, when invoking arrow functions using call()
, bind()
, or apply()
, the thisArg
parameter is ignored. You can still pass other arguments using these methods, though.
const obj = { name: "obj" }; const foo = () => this; // Attempt to set this using call console.log(foo.call(obj) === globalObject); // true // Attempt to set this using bind const boundFoo = foo.bind(obj); console.log(boundFoo() === globalObject); // true
“Function context” (MDN Web Docs). Retrieved November 14, 2023.
What is the benefit of using arrow functions on setTimeout()
?
Arrow functions create closures over the this
value of the enclosing execution context. So its this is permanently bound to the this of its enclosing function. With methods like setTimeout()
and EventTarget.prototype.addEventListener()
that usually require some kind of closure, instead of using call()
, apply()
, or bind()
to ensure that the function is executed in the proper scope we can now use arrow functions.
Example:
const obj = { count: 10, doSomethingLater() { // The method syntax binds "this" to the "obj" context. setTimeout(() => { // Since the arrow function doesn't have its own binding and // setTimeout (as a function call) doesn't create a binding // itself, the "obj" context of the outer method is used. this.count++; console.log(this.count); }, 300); }, }; obj.doSomethingLater(); // logs 11
What is the value of this
in constructors?
When a function is used as a constructor (with the new keyword), its this
is bound to the new object being constructed, no matter which object the constructor function is accessed on. The value of this
becomes the value of the new
expression unless the constructor returns another non–primitive value.
function C() { this.a = 37; } let o = new C(); console.log(o.a); // 37 function C2() { this.a = 37; return { a: 38 }; } o = new C2(); console.log(o.a); // 38
“Function context” (MDN Web Docs). Retrieved November 14, 2023.
What is the value of this
of a function invoked inside a super.method()
call?
When a function is invoked in the super.method()
form, the this
inside the method function is the same value as the this
value around the super.method()
call, and is generally not equal to the object that super
refers to. This is because super.method
is not an object member access like the ones above — it’s a special syntax with different binding rules.
class Base { static getName() { console.log(this.name); } } class Extended extends Base { static getName() { super.getName(); } } Extended.getName(); // Logs "Extended"
When calling super.prop
as a function, the this
value inside the prop
function is the current this
, not the object that super
points to. For example, the super.getName()
call logs "Extended"
, despite the code looking like it’s equivalent to Base.getName()
.
“Function context” (MDN Web Docs). Retrieved November 14, 2023.
Explain Class
context
A class can be split into two contexts: static
and instance
. Constructors, methods, and instance field initializers (public
or private
) belong to the instance
context. Static methods, static field initializers, and static initialization blocks belong to the static
context.
“Class context” (MDN Web Docs). Retrieved November 28, 2023.
What is the value of this
on the class static
context?
Static methods are not properties of this
. They are properties of the class
itself. Therefore, they are generally accessed on the class, and this
is the value of the class (or a subclass). Static initialization blocks are also evaluated with this
set to the current class.
Field initializers are also evaluated in the context of the class. Instance fields are evaluated with this
set to the instance being constructed. Static fields are evaluated with this
set to the current class. This is why arrow functions in field initializers are bound to the instance for instance fields and to the class for static fields.
class C { instanceField = this; static staticField = this; } const c = new C(); console.log(c.instanceField === c); // true console.log(C.staticField === C); // true
“Class context” (MDN Web Docs). Retrieved November 28, 2023.
What is the value of this
on the class instance
context?
Class constructors are always called with new
, so their behavior is the same as function constructors
: the this
value is the new instance being created. Class methods behave like methods in object literals — the this
value is the object that the method was accessed on. If the method is not transferred to another object, this
is generally an instance of the class
. Instance fields are evaluated with this
set to the instance being constructed.
“Class context” (MDN Web Docs). Retrieved November 28, 2023.
What is the value of this
on derived class
constructors?
Unlike base class constructors, derived constructors have no initial this
binding. Calling super()
creates a this binding within the constructor and essentially has the effect of evaluating the following line of code, where Base is the base class:
this = new Base();
Warning: Referring to this before calling super()
will throw an error.
Warning: Derived classes must not return before calling super()
, unless the constructor returns an object (so the this value is overridden) or the class has no constructor at all.
“Class context” (MDN Web Docs). Retrieved November 28, 2023.
What is the value of this
on the global context?
The this
value depends on what execution context the script runs in. At the top level of a script, this
refers to globalThis
whether in strict mode
or not. This is generally the same as the global object — for example, if the source is put inside an HTML <script>
element and executed as a script, this === window
.
const obj = { a: "Custom" }; // Variables declared with var become properties of 'globalThis'. var a = "Global"; function whatsThis() { return this.a; // 'this' depends on how the function is called } whatsThis(); // 'Global'; the 'this' parameter defaults to 'globalThis' in non–strict mode obj.whatsThis = whatsThis; obj.whatsThis(); // 'Custom'; the 'this' parameter is bound to obj
If the source is loaded as a module (for HTML, this means adding type="module"
to the <script>
tag), this
is always undefined
at the top level.
If the source is executed with eval()
, this
is the same as the enclosing context for direct eval, or globalThis
(as if it’s run in a separate global script) for indirect eval.
“Global context” (MDN Web Docs). Retrieved November 28, 2023.
How can you bind the value of this
in a function?
With the bind()
function method. For example, calling f.bind(someObject)
creates a new function with the same body and scope as f
, but the value of this
is permanently bound to the first argument of bind
, regardless of how the function is being called.
function f() { return this.a; } const g = f.bind({ a: "azerty" }); console.log(g()); // azerty const h = g.bind({ a: "yoo" }); // bind only works once! console.log(h()); // azerty const o = { a: 37, f, g, h }; console.log(o.a, o.f(), o.g(), o.h()); // 37 37 azerty azerty
“The bind() method” (MDN Web Docs). Retrieved November 29, 2023.
bind()
method
The bind()
function creates a new bound function. Calling the bound function generally results in the execution of the function it wraps, which is also called the target function. The bound function will store the parameters passed — which include the value of this
and the first few arguments — as its internal state.
Syntax
bind(thisArg) bind(thisArg, arg1) bind(thisArg, arg1, arg2) bind(thisArg, arg1, arg2, /* …, */ argN)
Parameters
-
thisArg - The value to be passed as the
this
parameter to the target function func when the bound function is called. If the function is not instrict mode
,null
andundefined
will be replaced with the global object, and primitive values will be converted to objects. The value is ignored if the bound function is constructed using thenew
operator. - arg1, …, argN Optional - Arguments to prepend to arguments provided to the bound function when invoking func.
Return value
A copy of the given function with the specified this value, and initial arguments (if provided).
“Function.prototype.bind() - JavaScript | MDN” (MDN Web Docs). Retrieved November 30, 2023.
call()
method
Normally, when calling a function, the value of this
inside the function is the object that the function was accessed on. With call()
, you can assign an arbitrary value as this when calling an existing function, without first attaching the function to the object as a property. This allows you to use methods of one object as generic utility functions.
Syntax
call(thisArg) call(thisArg, arg1) call(thisArg, arg1, arg2) call(thisArg, arg1, arg2, /* …, */ argN)
Parameters
-
thisArg - The value to use as this when calling func. If the function is not in
strict mode
,null
andundefined
will be replaced with the global object, and primitive values will be converted to objects. - arg1, …, argN Optional - Arguments for the function.
Return value
The result of calling the function with the specified this value and arguments.
“Function.prototype.call() - JavaScript | MDN” (MDN Web Docs). Retrieved November 30, 2023.
apply()
method
Normally, when calling a function, the value of this
inside the function is the object that the function was accessed on. With apply()
, you can assign an arbitrary value as this when calling an existing function, without first attaching the function to the object as a property. This allows you to use methods of one object as generic utility functions.
Syntax
apply(thisArg) apply(thisArg, argsArray)
Parameters
-
thisArg - The value of this provided for the call to func. If the function is not in
strict mode
,null
andundefined
will be replaced with the global object, and primitive values will be converted to objects. -
argsArray Optional
An array-like object, specifying the arguments with which func should be called, or null or undefined if no arguments should be provided to the function.
Return value
The result of calling the function with the specified this value and arguments.
“Function.prototype.apply() - JavaScript | MDN” (MDN Web Docs). Retrieved November 30, 2023.