A question on an #AppsScripts user forum led me into an investigation into the best way to extend a class, for example a Date
class, from inside a library so that the host project can use it.
Let's suppose we want to make a class BetterDate
that extends the date object so that it automatically calculates the result of .getTime()
once. (Maybe we don't want to waste time? rimshot)
We'll add an instance method on it to calculate how many days we have to wait (until our birthday). We also need a static object now()
on it so that we can get a now date that is an instance of BetterDate
.
This to me is most elegant:
// lib code
function augment(Obj) {
// add properties to the prototype, i.e. "instance methods"
return class BetterDate extends Obj {
/**
* @param {Any} value -
*/
constructor (value) {
if (value===undefined)
// if nothing passed, we need to call super with no arguments.
// woe is the javascripter overriding constructors of built-in objects
super();
else
super(value);
this.time = this.getTime();
}
/**
* @param {BetterDate} endDate - a future date as a BetterDate
*/
daysUntil (endDate) {
let diff = endDate.time - this.time;
return diff / (1000 * 60 * 60 * 24);
}
static now () {
return new BetterDate();
}
}
}
// project code:
function myFunction () {
const BetterDate = Lib.augment(Date);
const birthday = BetterDate('5/30/2021');
const now = BetterDate.now();
const days = now.daysUntil(birthday);
}