Tanveer Sayem / 2022-10-30
5 min read
this
in JavaScript is a reserved keyword. In most cases, the value of this
is determined by how a function is called(runtime binding). It can't be set by assignment during execution, and it may be different each time the function is called. The bind()
method can set the value of a function's this
regardless of how it's called, and arrow functions don't provide their own this
binding.
Let's see how this
behaves in different contexts.this
refers to the global object whether in strict mode
or not. We can see this by simply typing this
in the devtools of the browser.
this // Window {0: Window, window: Window, self: Window,...,
console.log(this === window) // true
this
inside a function, we are going to get two different outputs based on if we are in strict mode
or not.
So in a non-strict mode, we are getting the same global object in the case of browsers - it is window object like before. In JavaScriptfunction myFunc() { console.log(this); } myFunc(); // Window {0: Window, window: Window, self: Window,...,
this
first looks for the value
in the function curly braces, when it does not find any value
there, then it goes outside of the function scope and looks for the value
which is in the global context of the global object. This behavior of this
could be a source of a bug. So, in order to solve the issue, we can use use strict
Let's get another example:function myFunc() { 'use strict'; console.log(this); } myFunc(); // undefined
As you can see from the above examplefunction someFunc() { this.name = 'Rahim Shah'; } someFunc(); window.name; // 'Rahim Shah'
this.name
attached the name
with the global object which is the window
object in the browser. In case of strict mode it will throw a TypeError: Cannot set properties of undefined
this
is set to the object the method is called on.
In the following example, when customObj.message()
is invoked, inside the function this
is bound to the customObj
object.
const customObj = { name: 'Rahim', occupation: 'Developer', message: function() { console.log('Hey! my name is', this.name + ' and I am a ' + this.occupation); } } customObj.message(); // 'Hey! my name is', Rahim and I am a Developer'
this
binding is only affected by the most immediate member reference. In the following example, let's call a function in a nested object.
If we callconst customObj = { name: 'Rahim', occupation: 'Developer', nestedObj: { name: 'Karim', occupation: 'Engineer', message: function() {console.log('Hi, my name is ' + this.name);} } }
customObj.nestedObj.message();
we will get 'Hi, my name is karim'
back.this
in classes and functions is similar since classes are functions under the hood. Within a class constructor, this
is a regular object. All non-static methods within the class are added to the prototype of this
:
Note: Static methods are not properties ofclass Example { constructor() { const proto = Object.getPrototypeof(this); console.log(Object.getOwnPropertyNames(proto)); } first(){} second(){} static third(){} } new Example(); // ['constructor', 'first', 'second']
this
. They are properties of the class itself.
bind()
, call()
, apply()
method
We can specifically bind this
to an object with the call(), or apply()
method. For an example let's take our previous example of nested object.
If we runconst customObj = { name: 'Rahim', occupation: 'Developer', nestedObj: { name: 'Karim', occupation: 'Engineer', message: function() {console.log('Hi, my name is ' + this.name);} } }
customObj.nestedObj.message()
we are going to get the name printed as 'karim' but what if we want the 'Rahim' name instead? We can use the call()
method to achieve the desired result.
customObj.nestedObj.message.call(customObj) // Hi, my name is Rahim
apply()
method will get the same result as above.
Let's look at the bind()
method.
Calling someFunc.bind(someObj)
creates a new function with the same body and scope as someFunc
, but where this
occurs in the original function, in the new function it is permanently bound to the first argument of bind
, regardless of how the function is being used.
function someFunc() { return this.property; } const anotherObj = someFunc.bind({ property: 'some value'}) console.log(anotherObj()) // some value
this
will be set to the global object in the global code. In the following code, this
will return undefined:
If we runconst customObj = { name: 'Rahim', nestedObj = { name: 'Karim', msg: () => {console.log(this)} } }
customObj.nestedObj.msg()
will return window
object in browsers.Get emails from me about web development, tech, and early access to new articles.