dispatch函数的实现
消除if-else,switch-case
// dispatch函数的实现
import _ from 'underScore'
import Utils from '../lib/utils.js'
// 消除if-else,switch-case
function dispatch(...funs) {
let len = funs.length
return function(target, ...args) { // 第一次调用存储待调用函数,返回备用函数。第二次调用传入
let ret = undefined
for(let i = 0; i < len; i++) {
let fun = funs[i]
// ret = fun.apply(fun, [[target, args].flat()])
// [[0,1,2,3,4,5,6,7,8,9]],apply解构进去后剩下数组
ret = fun.apply(fun, Utils.constructor(target, args))
if(Utils.existy(ret)) return ret
}
return ret
}
}
// 组合对象属性
let toString = dispatch(Utils.invoker('toString', Array.prototype.toString), Utils.invoker('toString', String.prototype.toString))
console.log(toString('a'))
console.log(toString(_.range(10)))
function stringReverse(s) {
if(!_.isString(s)) return undefined
return s.split('').reverse().join('')
}
console.log(stringReverse('ok'))
console.log(stringReverse(1))
let rev = dispatch(Utils.invoker('reverse', Array.prototype.reverse), stringReverse) // 无默认值
rev = dispatch(Utils.invoker('reverse', Array.prototype.reverse), stringReverse, Utils.k(42)) // 默认值为42
console.log(rev('ok'))
console.log(rev([1, 2, 3])) // [3, 2, 1]
console.log(rev(1)) // 42
// 消除switch
function performCommonHardCoded(command) {
let ret
switch(command.type) {
case 'notify':
ret = 'notify message'
break;
case 'join':
ret = 'changeView message'
break;
default:
ret = 'default'
}
return ret
}
console.log( performCommonHardCoded({type: 'notify', message: 'hi'}))
console.log( performCommonHardCoded({type: 'join', message: 'hello'}))
console.log( performCommonHardCoded({type: 'wat'}))
function isa(type, action) {
return function(obj) {
if(type === obj.type) {
return action(obj)
}
}
}
// 将条件抽离成返回条件的函数,再使用for循环函数来执行if条件。
let performCommand = dispatch(isa('notify', obj => obj.message), isa('join', obj => obj.target), obj => obj.type)
// 组合成新的函数
// 为什么能组合成新的函数?performCommand返回一个缓存函数条件的待执行函数。
// 再继续缓存一个新的条件函数和一个待执行函数。
let performAdminCommand = dispatch(isa('kill', obj => 'shutdown ' + obj.hostName ), performCommand)
console.log(performAdminCommand({type: 'kill', hostName: 'localhost'}))
console.log(performAdminCommand({type: 'fail'}))
console.log(performAdminCommand({type: 'join', target: 'foo'}))