Reputation: 63
I am new to JS and came across the JS code in which analogy of JS'stop watch object was implemented. Here is the code:
function Stopwatch() {
let startTime, endTime, running, duration = 0;
this.start = function() {
if (running)
throw new Error('Stopwatch has already started.');
running = true;
startTime = new Date();
};
this.stop = function() {
if (!running)
throw new Error('Stopwatch is not started.');
running = false;
endTime = new Date();
const seconds = (endTime.getTime() - startTime.getTime()) / 1000;
duration += seconds;
};
this.reset = function() {
startTime = null;
endTime = null;
running = false;
duration = 0;
};
Object.defineProperty(this, 'duration', {
get: function() { return duration; }
});
}
I would like to ask some questions on the above code. The first question is when we use "running" variable in start method's if statement, does the value of "running" converted from being undefined(by default since it was not given a value) to true? The second question, after if statement in start method why running was assigned to true. The third question, since running was assigned to true in start method Is its value changed globally as well? Or globally the value of "running" remains undefined?
Upvotes: -1
Views: 90
Reputation: 1323
In javascript all the variables are populated with undefined until they are getting a value.
In your example variables startTime, endTime, running have undefined values when the an instance of Stopwatch is created (they are global in each instance).
start method checks the state of the running
variable and then if it has not got the value of true then it updates the value and starts the stopwatch by setting the startTime
variable.
stop method examines the state of running
and ensures if it has the proper value (to check if the start method has been called before). Then, it calculates the duration and sets the value into duration
variable.
Finally, reset method, simply resets all the values of variables.
Upvotes: 0
Reputation: 1074266
...when we use "running" variable in start method's if statement, does the value of "running" converted from being undefined(by default since it was not given a value) to true?
undefined
is a falsy value: It coerces to false
when used as a boolean, as it is in start
. The falsy values are undefined
, null
, 0
, NaN
, ""
, and of course, false
. All other values are truthy (including "0"
and "false"
, which sometimes surprises people).
The second question, after if statement in start method why running was assigned to true.
Because the body of the if (running)
statement isn't run, because if (running)
is false.
The third question, since running was assigned to true in start method Is its value changed globally as well?
There is only one running
variable in the code, which isn't global, but is accessible by all code within the Stopwatch
function (even after Stopwatch
returns). So setting it true
in start
means it's then true
throughout the code in Stopwatch
. (stop
sets to to false
again.)
So assume you've just created an instance of Stopwatch
. When you call start
:
if (running) throw...
doesn't throw
because running
is undefined
, which is falsy.running = true;
sets running
to true
. There's only one copy of running
(per Stopwatch
instance) so all the other code within Stopwatch
sees that one variable's current value.startTime = new Date();
saves the start date/time in startTime
. Like running
, there's only one of these variables (per Stopwatch
instance).If you then called start
again, if (running) throw...
would throw
, because running
is true
now.
Later, if you call stop
:
if (!running) throw...
doesn't throw
because running
is true
.running = false;
sets running
to false
.endTime = new Date()
sets endTime
to the current date/time.const seconds = (endTime.getTime() - startTime.getTime()) / 1000;
determines the time in seconds between when start
and stop
were called.duration += seconds
adds seconds
to the existing value in duration
. duration
starts out at 0
, but if you do start
/stop
and then start
/stop
again, it will record the total duration of both timers.Upvotes: 2
Reputation: 840
Javascript variables have lexical scope, so all of the variables defined on line 2 are available throughout function Stopwatch.
Javascript does a lot of type coercion of variables, especially in evaluating conditions. In javascript, the '!' (not) operator returns a boolean based on how the variable that it's operating on coerces.
When the function starts, running is declared, but not initialized, so javascript initialized it to undefined
. undefined
coerces to false
, so, !undefined === !false === true
.
In the start function, running
is set to true so that future checks of !running
will work as expected.
Upvotes: 0