JavaScript is the owner of "this"

I followed the tutorial to create a JavaScript stopwatch and am trying to expand it to work with multiple stopwatch (multiple instances of the class). The problem is that when I try to display the current value while the clock is ticking, I need to hardcode the class instance because using "this" does not work (on the line where I use console.log). I cut the code to a minimum to try to understand this aspect and insert what I have below:

function Timer(){ var time1 = null; var time2 = null; var timeLoop = null; function getTime(){ var day = new Date(); return day.getTime(); } this.start = function(){ time1 = getTime(); timeLoop = setInterval(function(){ time2 = getTime(); console.log(_Timer.duration()); //console.log(this.duration()); },500); } this.duration = function(){ return (time1 - time2) / 1000; } } 

I think the link below describes my problem, but I do not understand it enough to apply it here. Is the problem because the owner is this.start, not just that, and how can I change the code to work with any timer instance?

http://www.quirksmode.org/js/this.html

I included both the hard-coded string and the "this" string, which does not work.

Thanks,

Jarate

+6
source share
5 answers

If you want the this property to be consistent, you must bind the called functions.

For instance,

setInterval(function() { /* code here */ }.bind(this), 500)

Thus, the inner function this will be the same as the outer function.

+6
source

Whenever you see a function , you can assume that the value of this changes, so inside the callback function for the interval this is actually a window , not an object.

A simple solution is to simply store this in a variable

 function Timer(){ var time1 = null; var time2 = null; var timeLoop = null; function getTime(){ var day = new Date(); return day.getTime(); } this.start = function(){ var self = this; time1 = getTime(); timeLoop = setInterval(function(){ time2 = getTime(); console.log(self.duration()); },500); } this.duration = function(){ return (time1 - time2) / 1000; } } 
+3
source

this not a local variable, so it is not stored in closure. You need to assign a local variable:

 this.start = function(){ var self = this; time1 = getTime(); timeLoop = setInterval(function(){ time2 = getTime(); console.log(self.duration()); },500); } 
+1
source

Try:

 function Timer(){ var time1 = null; var time2 = null; var timeLoop = null; var _this = this; function getTime(){ var day = new Date(); return day.getTime(); } this.start = function(){ time1 = getTime(); timeLoop = setInterval(function(){ time2 = getTime(); console.log(_this.duration()); },500); } this.duration = function(){ return (time1 - time2) / 1000; } } 
0
source

Primarily. Javascript does not support OOP class. OOP with it, inheritance is a prototype.

The following is an example of how to implement OOP prototype functions using your timer example:

 function Timer(){ var time1 = null; var time2 = null; var timeLoop = null; } Timer.prototype.getTime = function(){ var day = new Date(); return day.getTime(); } Timer.prototype.start = function(){ time1 = this.getTime(); timeLoop = this.setInterval(function(){ time2 = this.getTime(); console.log(this.duration()); }.bind(this),500); } Timer.prototype.duration = function(){ return (time1 - time2) / 1000; } 

See the section "Custom Objects" MDN Javscript Regeneration

There is nothing wrong with the way this is shown in your textbook. It’s just a cleaner way, and the bind call is only needed for the console.log statement, which otherwise would associate this as window . If you get rid of it, you can also get rid of bind .

0
source

Source: https://habr.com/ru/post/971671/


All Articles