/**
* Iterate all validators to check it is valid or not
*/
function checker(/* validators */) {
var validators = _.toArray(arguments);
/**
* @param obj: validate target
*/
return function(obj) {
return _.reduce(validators, function(errors, validate) {
if (validate(obj)) {
return errors;
} else {
return _.chain(errors).push(validate.message).value();
}
}, []);
};
}
使用如下:
> var alwaysFalseFun = always(false);
> alwaysFalseFun.message = 'error message'
> checker(alwaysFalseFun)({})
<. ['error message']
alwaysFalseFun
为了携带message,在函数体上加一个message的属性,这显示很不自然。
创建一个生成验证器的高阶函数
function validator(message, fun) {
// 生成一个包装的函数,为了避免在真正的验证逻辑的函数上增加不必要的属性
var f = function() {
return fun.apply(fun, arguments);
};
f[messsage] = message;
return f;
}
函数“柯里化” ( currying ): 从一个函数返回另外一个函数,并在返回过程中捕获参数。
var checkCommand = checker(validator('must be a map'), function(obj) {
return _.object(obj);
});
checker
函数,使用高阶函数,它的参数将作为返回函数的配置。这是高阶函数很有价值的地方。高阶函数
将产生一个具体执行的函数
,函数的行为受高阶函数的参数
所影响。