What else could we do to bind the object like this keyword? | JS, TS, React and Angular Forum
J
JYOTI SHARMA Posted on 17/01/2022

function test(){

    method : function(){colsole.log(this)},

    method2 : ()=>{console.log(this)} //.bind(this)

 

}

 

 


Y
Yogesh Chawla Replied on 17/01/2022

What is the need of bind function?

See this problem:

let user = {
  firstName: "ABC",
  sayHi() {
    console.log(`Hello, ${this.firstName}!`);
  }
};

setTimeout(user.sayHi, 1000); // Hello, undefined!

This happened because setTimeout got the function user.sayHi separately from the object.

Solution 1:

let user = {
  firstName: "ABC",
  sayHi() {
    console.log(`Hello, ${this.firstName}!`);
  }
};

setTimeout(function() {
  user.sayHi(); // Hello, ABC!
}, 1000);

This works because of function expression, meaning we are calling the function normally
But there could be a problem with this approach too. See this:

let user = {
  firstName: "John",
  sayHi() {
    console.log(`Hello, ${this.firstName}!`);
  }
};

setTimeout(() => user.sayHi(), 1000);

// ...the value of user changes within 1 second
user = {
  sayHi() { console.log("Another user in setTimeout!"); }
};

// Another user in setTimeout!

If value inside the function changes frequently then object can print a old value using this approach.

 

To resolve this:

Solution 2: bind Function

let user = {
  firstName: "ABC"
};

function func() {
  console.log(this.firstName);
}

// bind this to user
let funcUser = func.bind(user); //All arguments are passed to the original func “as is” using bind

funcUser(); // ABC

or here:

let user = {
  firstName: "ABC",
  sayHi() {
    console.log(`Hello, ${this.firstName}!`);
  }
};

let sayHi = user.sayHi.bind(user); // (*)

// Now this can run without an object too
sayHi(); // Hello, ABC!

setTimeout(sayHi, 1000); // Hello, John!

// even if the value of user changes within 1 second
// sayHi uses the pre-bound value which is reference to the old user object
user = {
  sayHi() { console.log("Another user in setTimeout!"); }
};

 

So this approach is always considered as better:

Usually, we should do sth like this to bind all objects:

for (let key in user) {
  if (typeof user[key] == 'function') {
    user[key] = user[key].bind(user);
  }
}