Skip to content

Latest commit

 

History

History
67 lines (59 loc) · 1.53 KB

4.3-高阶函数-对象校验器.md

File metadata and controls

67 lines (59 loc) · 1.53 KB

Code

/**
 * 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 ): 从一个函数返回另外一个函数,并在返回过程中捕获参数。

Example

var checkCommand = checker(validator('must be a map'), function(obj) {
  return _.object(obj);
});

总结

  • checker 函数,使用高阶函数,它的参数将作为返回函数的配置。这是高阶函数很有价值的地方。
  • 高阶函数将产生一个具体执行的函数,函数的行为受高阶函数的参数所影响。