I have always had a plausible feeling about this in Javascript. Today I suddenly felt enlightened. I will record it here.
Let's look at a chestnut first:
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>using this</title><script type="text/javascript">var Car,tesla;Car=function () {this.start=function(){console.log('car started');};this.turnKye=function () {var carKey=document.getElementById('car_key');carKey.onclick=function () {this.start(); };}return this;}tesla=new Car();tesla.turnKye();</script></head><body><input type="button" id="car_key" value="test" /></body></html>At first glance, there is no problem with this code, but the wrong understanding of this ultimately leads to the wrong result. We bind the click event on the element car_key, and believe that nesting the binding click event in the car class can allow this dom element to access the car's this context. This method seems reasonable, but unfortunately it doesn't work.
In Javascript, this keyword always points to the owner of the scope being executed.
Please carefully understand the above sentence. As we know, function calls will produce a new scope, and a little onclick event is triggered, and this points to the dom element instead of the Car class.
So how do we do it to make it work properly? We usually assign this to a local free variable (such as that, _this, self, me, etc., which are reflected in many frameworks) to avoid the problems caused by scope. Here we use local variables to override the previous method:
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Usage of this</title></head><body><input type="button" id="car_key" value="test" /><script type="text/javascript">var Car,tesla;Car=function () {this.start=function(){console.log('car started');};this.turnKye=function () {var that=this;var carKey=document.getElementById('car_key');carKey.onclick=function () {that.start(); };}return this;}tesla=new Car();tesla.turnKye();</script></body></html>Since that is a free variable, the departure of the onclick event does not cause its redefinition.
If you are familiar with ES6, you can use the fat arrow symbol, which is simpler and easier to understand, as follows:
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Usage of this</title></head><body><input type="button" id="car_key" value="test" /><script type="text/javascript">var Car,tesla;Car=function () {this.start=function(){console.log('car started');};this.turnKye=function () {//var that=this;var carKey=document.getElementById('car_key');//carKey.onclick=function () {// that.start(); //};carKey.onclick=()=>this.start();}return this;}tesla=new Car();tesla.turnKye();</script></body></html>Of course, we can also use the binding function method to solve this problem: as follows
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Usage of this</title></head><body><input type="button" id="car_key" value="test" /><script type="text/javascript">var Car,tesla;Car=function () {this.start=function(){console.log('car started');};var click=function(){this.start(); }this.turnKye=function () {//var that=this;var carKey=document.getElementById('car_key');carKey.onclick=click.bind(this);}return this;}tesla=new Car();tesla.turnKye();</script></body></html>In fact, I only knew how to write these pitfalls when I was learning React and when I was binding events. At that time, I only knew how to write them like this, but I didn’t know what happened. Today I suddenly felt enlightened. Hope it will be helpful to everyone.