When we are learning about handling events in React.JS, we found that to pass a function as a callback we need bind this function before using it:
class App extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log(this);
}
render() {
return <button onClick={this.handleClick} />;
}
}
ReactDOM.render(<App />, document.getElementById("root"));
when the button is clicked, we can see that, the this points to instance of the App Component.
But, what happens when we remove the bind line?
As we can see on the above image, the this became undefined. However, whether we put a console.log(this)
on App's render method, we will see again, the this point to the App instance.
JavaScript function
In JavaScript environment we have a global object that is defined in a global context and the value associated to the this is defined according to the context of execution. Such that, if we inspect the this variable in a global context (outside of any function) its values will points to the global object.
As an example, in the browser, if we type this in the console, we get the window object as the associated value. In an another way, in Node CLI, we will get an object that will have all globally used function like console, process etc.
Function call
When we call a function, the internal method Call is executed, receiving as parameters: the this value and the list of function's arguments.
doSomeThing();
can be seen as
doSomeThing.call(thisValue, arguments);
When we call a function in a short way (doSomeThing();
), we can not especify the thisValue. So, if the function is called in a global context, its value will be associated with the global object.
Thus, in our example with React Class, it turns out that, when we pass the handleClick function as a callback its execution context change and the this value became undefined.
Okay, but why was the this value undefined? This happen because when we run the React App, our class is transpiled and run on strict mode [1][2].
As an example lets see the this value of a function in strict mode and one not.
function doSomeThing() {
console.log(this);
}
function doSomeThing() {
"use strict";
console.log(this);
}
As a solution to that, we can use Function.prototype.bind, as was done in the contructor method of the first example. But, the bind function can be implemented using closures.
function doSomeThing() {
"use strict";
console.log(this);
}
closured = function(thisValue) {
return doSomeThing.call(thisValue);
};
So, in this post we saw briefly how the this keyword works in JavaScript, however, without a detailed approach of the Execution Context that contains the associated value to the this.
Top comments (0)