This Keyword

Understanding this keyword in Javascript

				
					// "use strict";
//*************************This keyword in Javascript**************************************//

//-----------------------1. this === window------------------------------------
//refers to the object it belongs to
//if it is alone --> it will refer to global object

console.log(this); //window object
console.log(this === window); //true

//----------------------2. Regular function-->this is window object---------------------

//in a regular function
//global object -->window object
const test = function () {
  console.log("regular function", this); //window object
};
test();

//--------------------- 3. Regular function-->accessing var variable-----------------------

//in a regular function
//global object -->window object
var name1 = "name1";
const test1 = function () {
  console.log(this.name1); //-->name1 -->fetches from window object
};
test1();

//---------------------4. Regular function-->accessing let variable-----------------------

let name2 = "name2";
const test2 = function () {
  console.log(this.name2); //undefined
};
test2();

//---------------------5. Function inside object-->this is -->Owner Object ---------------
//console.log(this); --> owner object is --> empDetails

const empDetails = {
  empName: "Anurag",
  getEmpId: function () {
    console.log(this); //this refers to the owner object -->empDetails
    console.log(this.empName); //Anurag
  },
};

empDetails.getEmpId();

//---------------6. Function inside object-->this is -->undefined -->'Use Strict' mode -------

//---------------7. Using call to access this inside normal function-----------------------------------

this.Bike = "Normal Bike";

const buyBike = function (cost) {
  console.log(this); //output as below
  //first time -->Windows object
  //2nd call-->{Bike: 'Bullet 250cc'}
  //3rd call-->{Bike: 'Pulsar'}

  console.log(`I am buying ${this.Bike} at amount ${cost}`);
  //I am buying Normal Bike at amount 50k
  //I am buying Normal Bike at amount 70k
  //I am buying Bullet 250cc at amount 250k
  //I am buying Pulsar at amount 120k
};

this.Bullet = {
  Bike: "Bullet 250cc",
};

let Pulsar = {
  Bike: "Pulsar",
};

buyBike("50k");
buyBike.call(this, "70k");
buyBike.call(this.Bullet, "250k");
buyBike.call(Pulsar, "120k");

//-------------------8. Using call to access this inside (inner) normal function------------------

// var isStrict = (function () {
//   return !this;
// })();
// console.log("isStrict::", isStrict);

// var mode = (eval("var __temp = null"), typeof __temp === "undefined") ? "strict" : "non-strict";
// console.log("isStrict::", mode);

this.Bike1 = "Normal Bike";
const buyBike1 = function (cost) {
  console.log(`I am buying::: ${this.Bike1} at amount ${cost}`);
  //I am buying Normal Bike at amount 50k
  //I am buying Normal Bike at amount 70k
  //I am buying Bullet 250cc at amount 250k
  //I am buying Pulsar at amount 120k

  const innerFunction = function (cost) {
    console.log(this); //window object always

    console.log(`I am buying ${this.Bike1} at amount ${cost}`);
    //I am buying Normal Bike at amount 50k
    //I am buying Normal Bike at amount 70k
    //I am buying Normal Bike at amount 250k
    //I am buying Normal Bike at amount 120k
  };
  innerFunction(cost);
};

this.Bullet1 = {
  Bike1: "Bullet 250cc",
};

let Pulsar1 = {
  Bike1: "Pulsar",
};

buyBike1("50k");
buyBike1.call(this, "70k");
buyBike1.call(this.Bullet1, "250k");
buyBike1.call(Pulsar1, "120k");

//--------9. How to solve this issue in inner function ...*****let that = this*****-------

this.Bike2 = "Normal Bike";
const buyBike2 = function (cost) {
  let that = this;
  const innerFunction = function (cost) {
    console.log(that);
    console.log(`I am buying ${that.Bike2} at amount ${cost}`);
  };
  innerFunction(cost);
};

this.Bullet2 = {
  Bike2: "Bullet 250cc",
};

let Pulsar2 = {
  Bike2: "Pulsar",
};

buyBike2("50k");
buyBike2.call(this, "70k");
buyBike2.call(this.Bullet2, "250k");
buyBike2.call(Pulsar2, "120k");


//-------10. How to solve this issue in inner function ...*****CALL AND BIND*****------------

this.Bike3 = "Normal Bike";
const buyBike3 = function (cost) {
  const innerFunction = function (cost) {
    console.log(`I am buying ${this.Bike3} at amount ${cost}`);

    //  I am buying Normal Bike at amount 50k
    //  I am buying Normal Bike at amount 70k
    //  I am buying Bullet 250cc at amount 250k
    //  I am buying Pulsar at amount 120k
  };
  //innerFunction.call(this, cost);
  innerFunction.bind(this)(cost);
};

this.Bullet3 = {
  Bike3: "Bullet 250cc",
};

let Pulsar3 = {
  Bike3: "Pulsar",
};

buyBike3("50k");
buyBike3.call(this, "70k");
buyBike3.call(this.Bullet3, "250k");
buyBike3.call(Pulsar3, "120k");

//-------11. How to solve this issue in inner function ...*****ARROW FUNCTION*****-----------------

this.Bike4 = "Normal Bike";
const buyBike4 = function (cost) {
  const innerFunction = (cost) => {
    return console.log(`I am buying ${this.Bike4} at amount ${cost}`);
    //  I am buying Normal Bike at amount 50k
    //  I am buying Normal Bike at amount 70k
    //  I am buying Bullet 250cc at amount 250k
    //  I am buying Pulsar at amount 120k
  };
  innerFunction(cost);
};

this.Bullet4 = {
  Bike4: "Bullet 250cc",
};

let Pulsar4 = {
  Bike4: "Pulsar",
};

buyBike4("50k");
buyBike4.call(this, "70k");
buyBike4.call(this.Bullet4, "250k");
buyBike4.call(Pulsar4, "120k");

//---12. One more similar example will help you to understand----------------------

const royalBike = {
  name: "Royal Enfield",
  models: ["Royal Enfield Interceptor 650", "Royal Enfield Himalayan", "Royal Enfield Classic 500"],
  newModels() {
    this.models.forEach(function (model) {
      console.log(this); //window object
      console.log(`${this.name} has a new model ${model}`);
    });
  },
};

royalBike.newModels();

//so how to solve it ....again the 3 ways
//----------------------12.1 foreach takes this as second parameter---------
const royalBike1 = {
  name: "Royal Enfield",
  models: ["Royal Enfield Interceptor 650", "Royal Enfield Himalayan", "Royal Enfield Classic 500"],
  newModels() {
    this.models.forEach(function (model) {
      console.log(this);
      console.log(`${this.name} has a new model ${model}`);
    }, this);
  },
};

royalBike1.newModels();
//Royal Enfield has a new model Royal Enfield Interceptor 650
//Royal Enfield has a new model Royal Enfield Himalayan
//Royal Enfield has a new model Royal Enfield Classic 500


//----------12.2 let that = this ----------------------------------------
const royalBike2 = {
  name: "Royal Enfield",
  models: ["Royal Enfield Interceptor 650", "Royal Enfield Himalayan", "Royal Enfield Classic 500"],
  newModels() {
    let that = this;
    this.models.forEach(function (model) {
      console.log(that); //window object
      console.log(`${that.name} has a new model ${model}`);
    });
  },
};

royalBike2.newModels();
//Royal Enfield has a new model Royal Enfield Interceptor 650
//Royal Enfield has a new model Royal Enfield Himalayan
//Royal Enfield has a new model Royal Enfield Classic 500

//------------------------12.3. Arrow function  ----------------------
const royalBike3 = {
  name: "Royal Enfield",
  models: ["Royal Enfield Interceptor 650", "Royal Enfield Himalayan", "Royal Enfield Classic 500"],
  newModels() {
    this.models.forEach((model) => {
      console.log(this);
      console.log(`${this.name} has a new model ${model}`);
    });
  },
};
royalBike3.newModels();
//Royal Enfield has a new model Royal Enfield Interceptor 650
//Royal Enfield has a new model Royal Enfield Himalayan
//Royal Enfield has a new model Royal Enfield Classic 500

				
			
				
					//1.this object literal example ...normal function ...
let getProductDetails = () => {
  let product = {
    productId: "123LGMonitor",
    productName: "LG Ultra Wide Monitor",
    price: 55750,
    discount: 1500,
    finalPrice: function () {
      console.log(this); //product object
      return this.price - this.discount;
    },
  };
  return product.finalPrice();
};
console.log(getProductDetails()); //54250

//2.this object literal example ...Arrow function --error 
let getProductDetails1 = () => {
  let product = {
    productId: "123LGMonitor",
    productName: "LG Ultra Wide Monitor",
    price: 55750,
    discount: 1500,
    finalPrice: () => {
      //console.log(this); //window object
      //return this.price - this.discount;//error 
    },
  };
  return product.finalPrice();
};
console.log(getProductDetails1()); //error...Cannot read properties of undefined (reading 'price')

//3.this object literal example ...call method()
let getProductDetails2 = () => {
  let product = {
    productId: "123LGMonitor",
    productName: "LG Ultra Wide Monitor",
    price: 55750,
    discount: 1500,
    finalPrice: function () {
      return this.price - this.discount;
    },
  };

  let prod1 = {
    price: 55750,
    discount: 5000,
  };
  return product.finalPrice.call(prod1);
};
console.log(getProductDetails2()); //50750

//3.this object literal example ...apply method()
let getProductDetails3 = () => {
  let product = {
    productId: "123LGMonitor",
    productName: "LG Ultra Wide Monitor",
    price: 55750,
    discount: 1500,
    finalPrice: function () {
      return this.price - this.discount;
    },
  };
  let prod1 = {
    price: 55750,
    discount: 10000,
  };
  return product.finalPrice.apply(prod1);
};
console.log(getProductDetails3()); //45750

				
			

Guess the output

				
					const employee = {
  name: "anurag",
  getName: () => {
    console.log(this.name);
  },
};

employee.getName();


				
			
				
					/*
this inside the arrow function is window object

OUTPUT:-  undefined

----------normal function-----------
const employee = {
  name: "anurag",
  getName: function () {
    console.log(this.name);
  },
};

employee.getName(); //anurag
*/


				
			

Leave a Comment