-1

I'm new to JavaScript and I made a simple stopwatch constructor:

function Stopwatch() {
    var started = false;
    var elapsed;
    var start;
    d = new Date();
    this.duration = function() {
        if (started) {
            throw "Stopwatch is still running"
        } else {
            return (elapsed);
        }
    }
    this.start = function() {
        if (started) {
            throw "Stopwatch has already started"; 
        } else {
            start = d.getTime();
            started = true;
        }
    }
    this.stop = function() {
        if (!started) {
            throw "Stopwatch hasn't started";
        } else {
            elapsed = d.getTime() - start;
            started = false;
        }
    }
    this.reset = function() {
        started = false;
        elapsed = 0;
    }
}
let sw = new Stopwatch();
sw.start();

setTimeout(function () {
    sw.stop();
    console.log(sw.duration());
}, 500);

The logic of the errors works fine, but whenever I call sw.duration(), it always returns zero, and I'm not sure why that is since I'm using var instead of let. Please let me know.

Ry-
  • 218,210
  • 55
  • 464
  • 476
  • 3
    You should check out ES6 classes, because this isn’t the ideal way to create a constructor. Also, no reason to use a mix of `var` and `let` – as long as you have `let` available, you should never use `var`. Finally, implicit globals are bad, so make sure you’re in strict mode. – Ry- Nov 23 '21 at 02:41

1 Answers1

4

You're calling new Date only once, at the start of the constructor. Use Date.now instead (to get a number, to avoid having to call .getTime), and call it not only when you need to assign to start, but also in .stop, to get elapsed.

function Stopwatch() {
    var started = false;
    var elapsed;
    var start;
    this.duration = function() {
        if (started) {
            throw "Stopwatch is still running"
        } else {
            return (elapsed);
        }
    }
    this.start = function() {
        if (started) {
            throw "Stopwatch has already started"; 
        } else {
            start = Date.now();
            started = true;
        }
    }
    this.stop = function() {
        if (!started) {
            throw "Stopwatch hasn't started";
        } else {
            elapsed = Date.now() - start;
            started = false;
        }
    }
    this.reset = function() {
        started = false;
        elapsed = 0;
    }
}
let sw = new Stopwatch();
sw.start();
setTimeout(() => {
  sw.stop();
  console.log(sw.duration());
}, 500);
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320