"This" Problem Solved for Fring Object Method with SetInterval or AddeventListener
Lets talk about the problem with addEventlistener to a button. Consider the following code.
<button id = "call">Call</button>
<script>
var name = "global name";
var obj = {
name:"obj name",
call:function(){
alert(this.name);
}
};
obj.call();
// obj name
call.addEventListener("click",obj.call)
// when the button is clicked, windows alerts nothing.
</script>
The problem is we want to be able to refer to "obj name" when click on the button
Next Problem is with setInterval
<script>
var name = "global name";
var obj = {
name:"obj name",
call:function(){
console.log(this.name);
},
run:function(){
setInterval(this.call,200)
}
};
obj.run();
// global name
</script>
The problem is we want to show "obj name" on the console every 1 fifth of a second.
The above two examples are not workingm, neigher console.log nor alert refer to the obj and 'this' refers to the window object.
Solution
My solution for the addEventListener example is bellow
<button id = "call">Call</button>
<script>
var name = "global name";
var obj = {
name:"obj name",
call:function(){
alert(this.name);
}
};
obj.call();
// obj name
call.addEventListener("click",()=>{obj.call()})
// obj name
</script>
And my solution for the setInterval example us bellow
<script>
var name = "global name";
var obj = {
name:"obj name",
call:function(){
console.log(this.name);
},
run:function(){
setInterval(()=>{this.call()},200)
}
};
obj.run();
// obj name
</script>
Why "this"
One of the biggest reason why I always want to refer to this in a object, because of its reusability. Imagin a complex object with many methods not able to reder to itself using 'this' like this one.
<script>
var name = "global name";
var obj = {
name:"obj name",
call:function(){
console.log(obj.name);
},
run:function(){
setInterval(this.call,200)
}
};
obj.run();
// obj name
</script>
Everytime you change its code, I will have to remember to change the 'obj' in the code "console.log(obj.name);". If I don't, my obj will be broken. So this is why we need methods to refer to the own object.
By the way, the mechnism for the above solution to work is the difference between throwing "()=>{this.call()}" and "this.call" into either addEventListener or setInterval functions, resulting in 'this' in the executed function to refer to the object.
What about bind
I think using bind to solve the addEventListener problem which is fine, like below:
<button id = "call">Call</button>
<script>
var name = "global name";
var obj = {
name:"obj name",
call:function(){
alert(this.name);
}
};
obj.call();
// obj name
call.addEventListener("click",obj.call.bind(obj))
// obj name
</script>
I also use bind to solve the setInteravl, like below:
<script>
var name = "global name";
var obj = {
name:"obj name",
call:function(){
console.log(this.name);
},
run:function(){
setInterval(this.call.bind(this),200)
}
};
obj.run();
// obj name
</script>
Comments
Post a Comment