The behavior of the this keyword depends on the context in which it is used and the mode in which it is used. Used – strict or non-strict.
In the global context, this refers to the global object. What is a “global object” in JavaScript? It depends on the the environment in which the code is running. For example, in a web browser, this represents the window object, which represents the browser window. In a Node.js environment, this represents the global object. And for web workers, this represents the self object.
Global Context
For example, in a web browser when you run the following code:
console.log(this);//Window {window: Window, self: Window, document: document, name: "", location: Location, …}
In order to refer to the global context regardless of the location of the call, use the globalThis object
Function context
Within a function, this refers to the outer context. For functions defined in the global context, this is the object globalThis. For example:
//create simple function function foo() { var number = 1; console.log(this.number); } var number = 2; foo();//we will get 2. After all, the function is allocated in the global context
Without using this:
function foo() { var number = 1; console.log(number); } var number = 2; foo(); //1
But if we were to use strict mode, then this would be undefined in this case:
"use strict"//enable strict mode function foo() { var number = 1; console.log(this.number); } var number = 2; foo();//underfined
Object contex
In the context of an object, this refers to the same object. Consider an example:
var obj = { num: 1, foo: function () { console.log(this.num); } } var num = 2; obj.foo();// 1
Let’s consider a more complex example:
//create a function in which this is used in a global context function foo() { var num = 1; console.log(this.num); } var obj1 = { num: 2,//add the object property num foo: foo//add the function foo as a property of the object }; var obj2 = { num: 3, foo: foo//let's add the function foo as a property of the object }; var num = 4; foo();// We get 4. As discussed at the beginning of the article, the this function refers to a global object obj1.foo();// 2 obj2.foo();// 3
Objects define their own context in which their num property exists. And when calling the foo method by the outer the context in relation to the function will be the context of the objects.
Function in an object
this in functions uses the global context and in some cases this can cause unexpected results:
//create an object var obj1 = { num: 1,//let's set the property //create a method in which we use this shownum: function () { console.log(this.num); } } var obj2 = { num: 2, shownum: obj1.shownum//we will use the shownum method from the obj1 object }; var num = 3;//let's create a variable num in the global visibility area var shownum = obj1.shownum;//let's create a variable and assign it the obj1 object property obj1.shownum(); // 1 - everything is predicted here obj2.shownum(); // We will get 2. Here one could expect 1 because of what shownum: obj1.shownum, а у obj1 num = 1 //due to the fact that the function has a global visibility area, it leaves the context of the obj1 object and takes the value from the context of obj2 shownum(); //We will get 3. // in this case, the value for this.num will also be searched in the external context, that is, in the global context where the variable is defined var num = 3.
If we call a function from another function. The called function will also use the external context:
var num = 1; function shown1() { var num = 2; function show2() { console.log(this.num;) } show2(); } show1(); //1
Explicit binding of the function to the context
Using the call() and apply() methods, you can explicitly bind a function to a specific context:
function shownum() { console.log(this.num); } var obj1 = { num: 1 } var num = 2; shownum(); // 2 shownum.apply(obj1); //1 shownum.call(obj1);//1
Method blind
The f.bind(o) method allows you to create a new function with the same body and scope as f, but bound to object o:
Let’s consider an example:
const obj1 = { name: "John", greet: function() { console.log(`Hello, ${this.name}!`); } }; const bindedFunc = obj1.greet.bind(obj1); bindedFunc(); // Return 'Hello, John!'
This and arrow functions
In arrow functions, the object passed via this is taken from the parent context in which the object is defined arrow function. Consider the following example:
const person = { name: "Alexander", say: () => console.log(`Name: ${this.name}`) } person.say(); //Name: undefined
For an outer context in which an arrow function is defined – that is, for an object context, person this represents global object (browser window object).
Consider another example:
const person = { name: "Alexander", hello() { console.log("Hi"); let say = () => console.log(`Hello ${this.name}`); say(); } } person.hello();//Hello Alexander
The arrow function is now defined in the hello() method. this for this method represents the current person object, where
this method is defined. Therefore, in the arrow function, this will represent the person object.