Last active
December 2, 2016 10:19
-
-
Save gchudnov/77eb193ccd0789dbae6d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function createMultimethod(dispatch, noMatch) { | |
if(typeof dispatch !== 'function') { | |
throw new TypeError('dispatch must be a function'); | |
} | |
const dict = {}; | |
if(typeof noMatch == 'function') { | |
dict.noMatch = noMatch; | |
} | |
return new Proxy(() => { throw new Error('No match'); }, { | |
set(target, property, value) { | |
dict[property] = value; | |
return true; | |
}, | |
apply(target, thisArg, args) { | |
const value = dispatch.apply(null, args); | |
const func = (value && dict.hasOwnProperty(value) | |
? dict[value] | |
: (dict.hasOwnProperty('noMatch') | |
? dict['noMatch'] | |
: target)); | |
return func.apply(thisArg, args); | |
} | |
}); | |
} | |
// Usage: | |
let dispatchFunc = person => person && person.manners; | |
let noMatchFunc = () => { return 3.0; }; | |
let coffeePrice2 = createMultimethod(dispatchFunc, noMatchFunc); | |
coffeePrice2.polite = (person) => { | |
return 2.00; | |
}; | |
coffeePrice2.rude = (person) => { | |
return 6.00; | |
}; | |
let alice = { name: 'Alice', manners: 'polite' }; | |
let bob = { name: 'Bob', manners: 'rude' }; | |
console.log('$' + coffeePrice2(alice)); // $2 | |
console.log('$' + coffeePrice2(bob)); // $6 | |
console.log('$' + coffeePrice2()); // $3 | |
coffeePrice2.veryPolite = (person) => { | |
return 1.85; | |
}; | |
let carol = { name: 'Carol', manners: 'veryPolite' }; | |
console.log('$' + coffeePrice2(carol)); // $1.85 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment