How does event handlers with arrow functions achieve context binding

前端 未结 3 1370
误落风尘
误落风尘 2020-12-01 17:23

I know about the general theory of this binding (function call site what matters, implicit, explicit binding, etc...) and the methods to solving the problem of

3条回答
  •  南方客
    南方客 (楼主)
    2020-12-01 18:07

    In case 1, as you said, the context is picked up from the environment. For case 2, you have to remember that the class syntax in ES6 is just syntactic sugar over the more cumbersome prototype syntax on which JavaScript relies upon to implement OOP.

    Basically, in the second example, all you are doing is something like this:

    function demo() {
       // this is the constructor
    }
    demo.prototype.goToStore = function() {
      // handler
    };
    demo.prototype.render = function() {
      return React.createElement('button', onClick: this.goToStore);
    }
    

    As you can see, the onClick property is just receiving a reference to the function. Whenever that function is called, no this will be binded, and it will be run in the context of the window object.

    In older libraries, prior to the existence of modern transpilers, we used to do something like this ALL OVER THE PLACE:

    function demo() {
       // this is the constructor     
       this.goToStore = this.goToStore.bind(this);
       // same for every other handler
    }
    demo.prototype.goToStore = function() {
       // handling code.
    };
    demo.prototype.render = function() {
      // this goToStore reference has the proper this binded.
      return React.createElement('button', onClick: this.goToStore);
    }
    

    Nowadays, this last example I put is automatically handled by all modern transpilers. Babel basically does the autobinding in the constructor when you use the fat arrow method syntax in any class:

    class demo extends Anything {
      constructor() {
      }
      bindedMethod = () => {
        // my context will always be the instance!
      }
    }
    

    With subtle differences, all transpilers will move the definition of the bindedMethod to the constructor, where the this will be bound to the current instance running the constructor.

提交回复
热议问题