user11807902
user11807902

Reputation: 63

Confusion with how variables are used in JS

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

Answers (3)

Mahyar Mottaghi Zadeh
Mahyar Mottaghi Zadeh

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

T.J. Crowder
T.J. Crowder

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:

  1. if (running) throw... doesn't throw because running is undefined, which is falsy.
  2. 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.
  3. 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:

  1. if (!running) throw... doesn't throw because running is true.
  2. running = false; sets running to false.
  3. endTime = new Date() sets endTime to the current date/time.
  4. const seconds = (endTime.getTime() - startTime.getTime()) / 1000; determines the time in seconds between when start and stop were called.
  5. 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

Dov Rine
Dov Rine

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

Related Questions