In today's tutorial, I will show you how you can build a simple stopwatch in JavaScript using a constructor function.
A constructor function is a function that is used to create objects.
A Refresher on Objects
An object is an unordered collection of data in key-value pairs. A single pair of this data is called a property of that object.
Here are some ways to create an object in JavaScript;
- Using the object literal syntax { }
const obj = {
name : "simon"
}
console.log(obj);
// {name: 'simon'}
- Using a constructor function
function myProfile(name){
this.name = name;
}
const obj = new myProfile("simon");
console.log(obj);
// myProfile {name: 'simon'}
- Using a factory function
function myProfile(name){
return{
name : name
}
}
const obj = myProfile("simon");
console.log(obj);
// {name: 'simon'}
Having understood what objects are, and how you can create one, I will show you how to use a constructor function to build a stopwatch.
LET'S BEGIN
Our Constructor function will be named StopWatch and it will have variables and methods that will start our watch, stop our watch, reset our watch and display the duration.
A method is an object property that contains a function definition.
We will create variables inside our constructor function below, and these variables are only to be modified by methods within our function.
function StopWatch(){
let isStart = false; //start the watch
let startCount = 0; //record time started
let stopCount = 0; //record time stopped
let durationCount = 0; //calculate duration
let preDuration = 0; //calculate previous duration
}
Here are the variables within our constructor function;
- isStart
This variable will be used to check if our watch is started. If the value is true, it means that the watch is started but if the value is false, it means that the watch is stopped or not started.
- startCount
This variable will store the timestamp when our watch was started.
- stopCount
This variable will store the timestamp when our watch was stopped.
- durationCount
This variable stores the duration by finding the difference between startCount & stopCount.
- preDuration
This variable stores the previous duration as long as the stopwatch is not reset.
START METHOD
Now we are about to create the first method that will be responsible for starting our watch.
This method will check:
- If the watch has already been started ie (isStart == true).
If yes, it will log a message to the console informing the user that the watch has been started already.
If no, it will start the watch by retrieving the timestamp from a date object and storing it to startCount, then it will change the value of isStart to true.
- If the startCount is zero (0).
This variable holds the timestamp when our watch was started. If the value is zero (0), it will start the watch by retrieving the timestamp from a date object and storing it to startCount, then it will change the value of isStart to true.
It will then inform the user that the watch has been started.
- If none of the above is true
It will start the watch by retrieving the timestamp from a date object and storing it to startCount, then it will change the value of isStart to true.
It will then inform the user that the watch has been continued. ie resume.
function StopWatch(){
this.start = function(){
//check if watch is started
if(isStart === true){
console.log("Stop watch is already started");
}else if(startCount === 0){
let dt = new Date();
//retrieve timestamp from the date object
startCount = dt.getTime();
//start the watch by changing the value to true
isStart = true;
console.log("Stop watch has been started");
}else{
let dt = new Date();
//retrieve timestamp from the date object and store
startCount = dt.getTime();
//start the watch by changing the value to true
isStart = true;
console.log("Stop watch has been continued");
}
};
}
STOP METHOD
This method will be responsible for stopping our watch.
This method will check:
- If the watch was started. ie (isStart == true)
If not, it will inform the user that the watch has not been started.
If yes, it will stop the watch by retrieving the timestamp from a date object and storing it to stopCount, then it will change the value of isStart to false.
It will then inform the user that the watch has been stopped.
function StopWatch(){
this.stop = function(){
//check if stopwatch was started
if(isStart === false){
console.log("Stop watch is not started");
}else{
let dt = new Date();
//retrieve timestamp from the date object and store
stopCount = dt.getTime();
//stop the watch by changing the value to false
isStart = false;
console.log("Stop watch has been stopped");
}
};
}
DURATION METHOD
This method is responsible for calculating and returning the time our watch elapsed, in seconds.
It is important to note that using the method getTime() to retrieve the timestamp from a date object, returns the time in milliseconds and we need to divide this by 1000 to get the time in seconds.
Then we store the result to the previous duration variable (preDuration) so that we will keep adding it to the new duration as long as the watch is not reset.
You will also notice that I converted the time to minutes if it is greater than 60. This means that instead of showing 120 seconds, you would see 2 minutes instead.
Most of the results will end up with decimals so it is necessary to approximate it to 1 decimal place using the method toFixed().
function StopWatch(){
this.duration = function(){
let dur = 0;
//divide by 1000 to get the time in seconds
durationCount = (stopCount - startCount)/1000;
//check if previous duration was saved
if(preDuration === 0) {
//save new duration
preDuration = durationCount
}else{
//add previous duration to new duration
durationCount+=preDuration;
}
//check if duration is greater than 60 so we can convert to minutes
if(durationCount > 60){
//convert to minutes
dur = durationCount / 60;
//return duration in minutes by approximating to 1 decimal place
return (Number(dur.toFixed(1))+" Minutes");
}else{
//return duration in seconds by approximating to 1 decimal place
return (Number(durationCount.toFixed(1)) + " Seconds");
}
};
}
RESET METHOD
This is the last method of our stopwatch that will be used to reset the watch back to its initial state.
All it does is reset the variables declared within our constructor function to their initial state.
function StopWatch(){
this.reset = function(){
durationCount = startCount = stopCount = preDuration = 0;
isStart = false;
return true;
}
}
Here's the full code
function StopWatch(){
let isStart = false; //start the watch
let startCount = 0; //record time started
let stopCount = 0; //record time stopped
let durationCount = 0; //calculate duration
let preDuration = 0; //calculate previous duration
//start method
this.start = function(){
//check if watch is started
if(isStart === true){
console.log("Stop watch is already started");
}else if(startCount === 0){
let dt = new Date();
//retrieve timestamp from the date object
startCount = dt.getTime();
//start the watch by changing the value to true
isStart = true;
console.log("Stop watch has been started");
}else{
let dt = new Date();
//retrieve timestamp from the date object and store
startCount = dt.getTime();
//start the watch by changing the value to true
isStart = true;
console.log("Stop watch has been continued");
}
};
//stop method
this.stop = function(){
//check if stopwatch was started
if(isStart === false){
console.log("Stop watch is not started");
}else{
let dt = new Date();
//retrieve timestamp from the date object and store
stopCount = dt.getTime();
//stop the watch by changing the value to false
isStart = false;
console.log("Stop watch has been stopped");
}
};
//duration
this.duration = function(){
let dur = 0;
//divide by 1000 to get the time in seconds
durationCount = (stopCount - startCount)/1000;
//check if previous duration was saved
if(preDuration === 0) {
//save new duration
preDuration = durationCount
}else{
//add previous duration to new duration
durationCount+=preDuration;
}
//check if duration is greater than 60 so we can convert to minutes
if(durationCount > 60){
//convert to minutes
dur = durationCount / 60;
//return duration in minutes by approximating to 1 decimal place
return (Number(dur.toFixed(1))+" Minutes");
}else{
//return duration in seconds by approximating to 1 decimal place
return (Number(durationCount.toFixed(1)) + " Seconds");
}
};
//reset method
this.reset = function(){
durationCount = startCount = stopCount = preDuration = 0;
isStart = false;
return true;
};
}
In order to test our watch, you need to copy & paste the above constructor function into your browser's console, create an instance of the object, and test run!
Here's a list of the methods;
start(): This method starts the watch or resumes a stopped watch.
stop(): This method stops the watch.
duration(): This method calculates and returns the time elapsed.
reset(): This method resets the watch to its initial state
//create new instance of the object
let watch = new StopWatch();
//start the watch
watch.start();
//stop the watch after 5 seconds
watch.stop();
//caculate duration
console.log(watch.duration());
Here's my result
When I want the watch to continue from where it stopped, I would simply invoke the start() method without having to reset the watch.
What if we made the Stopwatch run for a couple of minutes?
If you ever need to reset the watch, simply invoke the reset method reset() on your object instance.
You can play with your new computer-based JavaScript stopwatch and check the consistency of your results by timing your start & stop, then comparing it with your local stopwatch. Who knows? They might just be the same.
You've reached the end of my article.
EXTRA
I recently launched a JavaScript package that validates your HTML forms using validation rules, regular expressions and form input attributes.
I will appreciate if you spared a few seconds to check out this wonderful package.
Thank You.
Image credit: Vecteezy.com
Top comments (0)