Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is JavaScript bind() necessary?

The problem in example 1 is 'this' referring to the global name instead of the myName object.

I understand the use of bind() in setting the value of this to a specific object, so it solves the problem in example 1, but why does this problem occur in the first place? Is it just the way Javascript was created?

I'm also wondering why example 3 solves the issue and the difference between example 2 and 3.

this.name = "John"    var myName = {    name: "Tom",    getName: function() {      return this.name    }  }    var storeMyName = myName.getName; // example 1  var storeMyName2 = myName.getName.bind(myName); // example 2  var storeMyName3 = myName.getName(); // example 3    console.log("example 1: " + storeMyName()); // doesn't work  console.log("example 2: " + storeMyName2()); // works  console.log("example 3: " + storeMyName3); // works
like image 272
Tom Avatar asked Dec 30 '16 05:12

Tom


1 Answers

Why is JavaScript bind() necessary?

The value of this is determined by how a function is called. If it is you who calls the function then there is usually no need to use .bind, since you have control over how to call the function, and therefore its this value.

However, often it is not you who calls the function. Functions are passed to other functions as callbacks and event handlers. They are called by other code and you have no control over how the function is called, and therefore cannot control what this will refer to.

If your function requires this to be set to a specific value and you are not the one calling the function, you need to .bind the function to a specific this value.

In other words: .bind allows you to set the value of this without calling the function now.

Here is comparison of referring to/calling functions:

                    +-------------------+-------------------+                     |                   |                   |                     |      time of      |       time of     |                     |function execution |    this binding   |                     |                   |                   | +-------------------+-------------------+-------------------+ |                   |                   |                   | |  function object  |      future       |      future       | |         f         |                   |                   | |                   |                   |                   | +-------------------+-------------------+-------------------+ |                   |                   |                   | |   function call   |       now         |        now        | |        f()        |                   |                   | |                   |                   |                   | +-------------------+-------------------+-------------------+ |                   |                   |                   | |     f.call()      |       now         |        now        | |     f.apply()     |                   |                   | |                   |                   |                   | +-------------------+-------------------+-------------------+ |                   |                   |                   | |     f.bind()      |      future       |        now        | |                   |                   |                   | +-------------------+-------------------+-------------------+ 

I'm also wondering why example 3 solves the issue and the difference between example 2 and 3.

Example 1/2 and 3 couldn't be more different. storeMyName and storeMyName2 contain functions, which are called in the future, whereas storeMyName3 contains the result of calling myName.getName() at that moment.


Further reading material:

  • How does the "this" keyword work?
  • MDN - this
  • YDKS - this & Object Prototypes
  • How to access the correct `this` context inside a callback?
like image 136
Felix Kling Avatar answered Oct 04 '22 01:10

Felix Kling