/**
* @author: K. Lae Kettavong
* @date: 2/13/19
* @description: Using IIFE to encapsulate class private members and leveraging closure to demonstrate currying
*/
const ValidInteger = (() => {
//private fields
let value
const cache = new Map()
return class{
constructor(val){
this.validateNum(val)
value = val
}
addNumber(num){
this.validateNum(num)
return () => {
if(cache.has(num)){
//no need to recalculate, just fetch from cache
console.log(`${cache.get(num)}...from cache`)
return cache.get(num)
} else {
const total = value + num
cache.set(num, total)
return total
}
}
}
validateNum(num){
Validator.ensureInteger(num)
}
}
})()
class Validator{
static ensureInteger(val){
if(!val || typeof(val) !== 'number') throw new TypeError('Invalid argument, must be a number')
}
}
const validInt10 = new ValidInteger(10)
console.log(validInt10.addNumber(5)()) //15
console.log(validInt10.addNumber(7)()) //17
console.log(validInt10.addNumber(12)()) //22
console.log(validInt10.addNumber(5)()) //15...from cache
const validInt100 = new ValidInteger(100)
console.log(validInt100.addNumber(20)()) //120
console.log(validInt100.addNumber(10)()) //110
console.log(validInt100.addNumber(55)()) //155
console.log(validInt100.addNumber(10)()) //110..from cache
console.log(validInt100.value) //undefined...cannot access private fields
console.log(validInt100.addNumber('30')()) // throws TypeError