this keyword

The this keyword refers to the current context.

When this is used in browser on global level, it refers to the window object, i.e. this === window.

When this is used inside methods, it refers to the object that it belongs to. And as a special case, when this is used in event handler, it refers to object, where event occurs.

var obj = {

prop: 23,

method1: function(){
  // console.log(prop);
  console.log(this.prop);
  }
};

obj.method1();
class MyCls {
  prop = 23,
  method1 {
    // console.log(prop);
    console.log(this.prop);
  }
}
new MyCls().method1();
function MyCls(){

this.prop = 23;
var data = "data";

this.method1 = function(){
  //console.log("m1",prop);
  console.log(this.prop);
  //console.log("m1", this.data);
  console.log(data);
  };
}

MyCls.prototype.method2 = 
 function(){
   // console.log("m2",prop);
   console.log("m2",this.prop);
   // console.log("m2", data);
   // out undefined value
   console.log("m2", this.data);
    };

var obj = new MyCls();
obj.method1();
obj.method2();

When this is used in function call, it refers to owner of function.

var gData="data";
    
function f(){
    var lData1="local data";
    this.lData2="local data 2";
    console.log(this.gData);
    
    function f2(){
        console.log("f2 gData: ", gData);
        console.log("f2 this.gData:", this.gData);
        console.log("f2 lData1:", lData1); 
        console.log("f2 this.lData2:", this.lData2);
        // out undefined
        console.log("f2 this.lData1:", this.lData1);
    }
    
    f2();
}   
    
f();

Finally, when this is used in function call in strict mode, it contains undefined value.

"use strict";
function func() {
  // out undefined
  console.log(this);
} 

func();

this shadowing

Suppose we write method, where we use local callback function. As you saw every function has own this. Thus this of callback function will hide this of method and we can't access to other object properties and methods inside callback.

It can be resolved by saving this value in other variable in outer scope of callback function. Other decision is using lambdas.

function MyCls(){
var self = this;
this.data ="data";
   
// method using callback   
this.start = function(){
        
  // callback function      
  setTimeout(function (){ 
     // out undefined
    console.log(this.data);
    console.log(self.data);
        }, 2000);        
  }
}
  
new MyCls().start();
function MyCls(){
this.data ="data";
   
// method using callback   
this.start = function(){
        
  // callback function      
  setTimeout(()=>{ 
    console.log(this.data);
        }, 2000);        
  }
}
  
new MyCls().start();
class MyCls{

  data ="data";
    
  start(){ 
    var self = this;  
    setTimeout(function(){ 
      console.log(self.data);
      // out undefined
      console.log(this.data);
    } , 2000);      
  }  
}
  
new MyCls().start();