this keyword in Javascript

·

4 min read

This keyword in javascript is used to refer to objects. This keyword points to a different object depending on how it is used. For a regular function, the pointing of this keyword depends on how and where the function is being called. For the arrow function, this keyword will not bind only it will take the reference of its parent's (location reference) this object and will use that as its reference object(this).

We can see the benefits of this keyword while using ES6 classes or constructor functions. Javascript will explicitly create a new object called this and it will be returned also explicitly. As we know that the ES6 classes and constructor functions (even Objects) will have a hidden object called prototype. Javascript will explicitly link the prototype object and this(object) so that there will be a prototype chain created between both objects and we can access the methods or properties inside the prototype using the keyword this before the prototype method or properties.

this.prototype."method-name"(). → we can invoke a method like this.

this.prototype."property-name" = new value. → we can assign a new value to a prototype property like this.

this in Regular Functions

For regular functions, if we invoke the method simply then it will point to the global object(window).

function displayName() {
console.log(`Hi ${this.name}`); // this --> window
}

function displayFood() {
displayName()
console.log(`Please eat ${this.food}`); // this --> window
}

displayFood()

Implicit Binding of this

  • If we implicitly bind the object like:-

ObjectName.methodName() → then in this case this keyword inside the method (methodName) will be pointing to that particular object (ObjectName).

let johnObj = {
  firstName: 'john',
  lastName: 'Doe',
  work: 'Doctor',
  fullName: function() {
    return `${this.firstName} ${this.lastName}.`;
  },
  workFunction: sayWork
}

let ronObj = {
  firstName: 'Ron',
  lastName: 'wisely',
  work: 'Wizard',
  fullName: function() {
    return `${this.firstName} ${this.lastName}.`;
  },
  workFunction: sayWork
}

function sayWork() {
  return `${this.firstName} ${this.lastName} is ${this.work}.`;
}

console.log(ronObj.fullName())  //this --> ronObj
console.log(ronObj.workFunction()) //this --> ronObj

console.log(johnObj.fullName()) //this --> johnObj
console.log(johnObj.workFunction()) //this --> johnObj

Explicit binding and hard binding of this

  • If we do explicit binding using the .call(object, parm1,parm2…), .apply(object, [parm1,parm2, …]), or .bind(object, parm1,parm2…) methods:-

Then in these cases, this keyword will take reference of the object that is passed inside the parameter.

Hard binding is done using .bind(object, parm1,parm2…) method

let ironMan = {
  name: 'Iron Man',
  power: 'Iron suit',
  sayPower: function () {
    console.log(`I  have ${this.power}.`); //this --> ironMan 
  }
}

let spiderMan = {
  name: 'Spider Man',
  power: 'Spider suit',
  sayPower: function () {
    console.log(`I  have ${this.power}.`); //this --> spiderMan 
  }
}

let thor = {
  name: 'Thor',
  power: 'Hammer',
  sayPower: function () {
    console.log(`I  have ${this.power}.`); //this --> thor
  }
}

ironMan.sayPower();
spiderMan.sayPower();

function sayNameAndPower() {
  console.log(`I am ${this.name}, i have ${this.power}.`)
}

sayNameAndPower.call(spiderMan); //this --> spiderMan 
sayNameAndPower.apply(ironMan); //this --> ironMan

let callThorFunction = sayNameAndPower.bind(thor) //this --> thor

callThorFunction();

this in Arrow Functions

In the case of the arrow function, it does not depend on how you call the function it will take reference of its parent object(this) since the arrow function does not bind the object.

let hulkObj = {
    name: 'Hulk',
    power: 'Samsh'
  }

  function parent() {


    let captianObj = {
    name: 'Captian America',
    power: 'Shield',
    sayPower: function () {
    console.log(`I  have ${this.power}.`); //this --> captianObj 
  }
  }

    let thor = {
  name: 'Thor',
  power: 'Hammer',
  sayPower: function () {
    console.log(`I  have ${this.power}.`); //this --> thor 
  }
}

    function regular() {
      console.log(`I am the this from regular Function ${this.name}`);
    }  //this --> depends on parent

  let arrowFunction = () => {
    console.log(`I am the this from arrow Function ${this.name}`)
  } //this --> depends depends on parent

    // regular() //this --> window
    // arrowFunction() //this --> window

    thor.sayPower() //this --> thor

  regular.call(captianObj)  //this --> captianObj
  arrowFunction.call(captianObj); //this --> hulkObj

return captianObj;
}
// parent()
  parent.call(hulkObj);

since we are invoking the parent function using the .call method and implicitly setting this of the parent function to hulkobj the arrowFunction which is the child of the parent function is taking the reference of hulhObj for this. if we had invoked the parent function in a regular way like parent() the arrow function would take the reference for this as the global window object and since the global window object has no property called name it will be undefined