Shashwat Kumar Shashwat Kumar -4 years ago 130
Javascript Question

Javascript not able to make common functions for a prototype

I am trying to make timer in javascript using a prototype. Each time a new timer is created, a object of prototype is created. There are methods to increase time and print each second. The whole code snippet is as follows:



function Timer(elem) {

this.interval = null;
this.currentTime = {
sec: 0,
min: 0,
hr: 0
};
this.elem = elem;
};

Timer.prototype.start = function() {
var self = this;
if (!self.interval) {
self.interval = setInterval(update, 1000);
}

function update() {
incrementTime();
render();
}

function render() {
self.elem.innerText = getPrintableTime();
}

function incrementTime() {
self.currentTime["min"] += Math.floor((++self.currentTime["sec"]) / 60);
self.currentTime["hr"] += Math.floor(self.currentTime["min"] / 60);
self.currentTime["sec"] = self.currentTime["sec"] % 60;
self.currentTime["min"] = self.currentTime["min"] % 60;
}

function getPrintableTime() {
var text = getTwoDigitNumber(self.currentTime["hr"]) + ":" + getTwoDigitNumber(self.currentTime["min"]) + ":" + getTwoDigitNumber(self.currentTime["sec"]);
return text;
}

function getTwoDigitNumber(number) {
if (number > 9) {
return "" + number;
} else {
return "0" + number;
}
}
};
module.exports = Timer;





I have all methods in
start
function. The problem is that for each new object of
Timer
, new space for each method will be used which is very inefficient. But when I try to put methods outside of
start
function, they lose access to
self
variable. You can see that there is
setInterval
function used which will be calling these methods per second. I cannot use
this
also as
this
will be instance of Window in subsequent calls.

How can I solve this situation by only keeping one instance of all the interior methods?

Answer Source

You can use apply to use functions defined outside of prototype with correct this context.

function Timer(elem) {

  this.interval = null;
  this.currentTime = {
    sec: 0,
    min: 0,
    hr: 0
  };
  this.elem = elem;
};

function update() {
  incrementTime.apply(this);
  render.apply(this);
}

function render() {
  this.elem.innerText = getPrintableTime.apply(this);
}

function incrementTime() {
  this.currentTime["min"] += Math.floor((++this.currentTime["sec"]) / 60);
  this.currentTime["hr"] += Math.floor(this.currentTime["min"] / 60);
  this.currentTime["sec"] = this.currentTime["sec"] % 60;
  this.currentTime["min"] = this.currentTime["min"] % 60;
}

function getPrintableTime() {
  var text = getTwoDigitNumber(this.currentTime["hr"]) + ":" + getTwoDigitNumber(this.currentTime["min"]) + ":" + getTwoDigitNumber(this.currentTime["sec"]);
  return text;
}

function getTwoDigitNumber(number) {
  if (number > 9) {
    return "" + number;
  } else {
    return "0" + number;
  }
}

Timer.prototype.start = function() {
  var self = this;
  if (!self.interval) {
    self.interval = setInterval(function() {
      update.apply(self);
    }, 1000);
  }
};

document.addEventListener('DOMContentLoaded', function() {
  var timer = new Timer(document.getElementById('timer'));
  timer.start();
}, false);
<div id="timer"></div>

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download