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
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.