What is this in JS?

  1. This refers to an Object
  2. Behaviour of this in a Object: this refers to the object.
  3. The value of this depends on how the function is invoked.
  4. Behaviour of this in a Function: this refers to window object.
  5. Arrow Functions: Arrow functions don’t have a defined this. Instead they treat it as a variable and they try to get the value lexically (inherit from parent scope).
  6. Normal function will look this inside parent. If not found points to Window.
  7. Arrow function will look this inside parent‚s parent. Then goes up lexically.

1. this inside normal function defined inside a object

const person = {
  name: "Arjunan",
  getName: function () {
    return this.name + " is my name";
  },
};

console.log(person.getName());

// Output:
Arjunan is my name

2. this inside function

function test() {
  console.log(this);
}
test();

// Output:
Window {0: Window, window: Window, self: Window, document: document, name: '', location: Location, …}

3. this inside arrow function defined inside a object

const person = {
  name: "Arjunan",
  getName: () => {
    return this.name + " is my name";
  },
};
console.log(person.getName());

// Output:
undefined is my name

4. this inside inner normal function of a object

function User() {
  this.name = "John Doe";
  this.score = 20;
  this.sayUser = function () {
    console.log(this.name);

    function innerFunction() {
      console.log(this.name);
    }

    innerFunction();
  };
}
let name = new User();
name.sayUser();

// Output:
John Doe
undefined

5. this inside inner arrow function of a object

function User() {
  this.name = "John Doe";
  this.score = 20;
  this.sayUser = function () {
    console.log(this.name);

    const innerFunction = () => {
      console.log(this.name);
    };

    innerFunction();
  };
}
let name = new User();
name.sayUser();

// Output:
John Doe
John Doe

6. What is the output?

this.a = 5;
console.log(this.a); // 5

function Example1() {
  console.log(this.a);
}
Example1(); // 5

const Example2 = () => {
  console.log(this.a);
};
Example2(); // 5

7. this inside a Class

this inside class refers to everything inside the constructor.

class User {
  constructor(n) {
    this.name = "Arjun";
    this.age = n;
  }

  getName() {
    console.log(this);
    console.log(this.name);
  }
}

let user = new User(5);
user.getName();
// User { name: 'Arjun', age: 5 }
// Arjun

8. What is the output?

While callling the function makeUser(), this is pointing to parent window object.

function makeUser() {
  return {
    name: "Arjun",
    ref: this,
  };
}

const user = makeUser();
console.log(user.ref.name);
// undefined

-----

function makeUser() {
  return {
    name: "Arjun",
    ref() {
      return this;
    },
  };
}

const user = makeUser();
console.log(user.ref().name);
// Arjun

-----

const User = {
  name: "Arjunan",
  age: 12,
  ref: this,
};

console.log(User.ref);
// Window {0: Window, window: Window, self: Window, ...}

9. What is the output?

setTimeout is calling the getName as Callback Function, not as a Method. To fix this call the function inside a dummy normal/arrow function so it will point as a Method.

const User = {
  name: "Arjun",
  getName() {
    console.log(this.name);
  },
};

User.getName(); // Arjun
setTimeout(User.getName, 1000); // undefined
setTimeout(() => User.getName(), 1000); // Arjun

10. Create an Object Calculator

const Calculator = {
  read() {
    this.a = +prompt("a = ", 0);
    this.b = +prompt("b = ", 0);
  },
  sum() {
    console.log(this.a + this.b);
  },
  mul() {
    console.log(this.a * this.b);
  },
};

Calculator.read(); // a = 13, b = 3
Calculator.sum(); // 16
Calculator.mul(); // 39

11. The diff between var, let and const in this

var a = 1;
let b = 2;
const c = 3;

function callback() {
  console.log(this.a, this.b, this.c);
}

callback();
// 1 undefined undefined

12. Output of callback function?

When we call the callback function it will first look inside parent for length. Since not found it will look inside window object.

var length = 3;

function callback1() {
  console.log(this.length);
}

const callback2 = () => {
  console.log(this.length);
}

const Obj = {
  length: 5,
  getLength(fn1, fn2) {
    fn1();
    fn2();
  },
};

Obj.getLength(callback1, callback1); // 3 3

13. Arguments length property

Here the parent of callback function is array and array has a length property. So it will return length of arguments.

var length = 3;

function callback() {
  console.log(this.length);
}

const Obj = {
  length: 5,
  getLength() {
    // arguments = [callback, 2, 3, 4]
    arguments[0]();
  },
};

Obj.getLength(callback, 2, 3, 4); // 4

14. Implicit Binding of this

In JavaScript, the this keyword is a special variable that is implicitly set by the runtime environment, and its value is determined by how a function is invoked. The concept of implicit binding of this refers to the way this is automatically bound to an object based on the context of the function invocation.

this is not bound to Obj because sayNameFunc is invoked without any context, since it is assigned to a variable.

let Obj = {
  name: "Example",
  sayName: function () {
    console.log(this.name);
  },
};

Obj.sayName(); // Example
let sayNameFunc = Obj.sayName;
sayNameFunc(); // undefined

15. Chaining of Methods

const Calc = {
  total: 0,
  add(num) {
    this.total += num;
    return this;
  },
  mul(num) {
    this.total *= num;
    return this;
  },
  sub(num) {
    this.total -= num;
    return this;
  },
  div(num) {
    this.total /= num;
    return this;
  },
};

const result = Calc.add(10).mul(2).div(5).sub(1);
console.log(result.total); // 3