Skip to content

Instantly share code, notes, and snippets.

@KooiInc
Last active April 17, 2025 14:26
Show Gist options
  • Save KooiInc/e250a4c80c3de4da45a4e506cb96d3eb to your computer and use it in GitHub Desktop.
Save KooiInc/e250a4c80c3de4da45a4e506cb96d3eb to your computer and use it in GitHub Desktop.
A counter generator
// A class free Object Oriented counter factory function
// See https://www.researchgate.net/publication/347727033_How_JavaScript_Works, chapter 13
function countGeneratorFactory() {
const valueOrDefault = ({value, defaultValue, forType = Number} = {}) =>
value?.constructor === forType ? value : defaultValue;
return function({from, to, step, reUsable} = {}) {
[from, to, step,reUsable] = [
valueOrDefault({value: from, defaultValue: 0}),
valueOrDefault({value: to, defaultValue: Number.MAX_SAFE_INTEGER}),
valueOrDefault({value: step, defaultValue: 1}),
valueOrDefault({value: reUsable, defaultValue: false, forType: Boolean})
];
if (to < from) {
[from, to] = [to, from];
}
if (step > to) {
step = 1;
}
const initials = [from, to, step, reUsable]
let count = from;
const me = {
get plus() {
count += count < to ? step : reUsable ? -to : 0;
return me;
},
get minus() {
count -= count < to ? step : reUsable ? -from : 0;
return me;
},
get reset() {
count = from;
return me;
},
get value() { return count; },
valueOf() { return count; },
toString() { return String(count); },
loopAsc(callback) {
if (callback?.constructor !== Function) { return me; }
count = reUsable ? from : count;
while(count < to) {
callback();
count += step;
}
// re-use
reUsable && me.reset;
},
loopDesc(callback) {
if (callback?.constructor !== Function) { return me; }
count = reUsable ? to : count;
while(count > from) {
callback();
count -= step;
if (count < from) {
count = from;
callback();
}
}
// re-use
reUsable && me.reset;
}
}
return Object.freeze(me);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment