首页 > 代码库 > 函数包装器

函数包装器

     在看express的源码中,经常看到函数包装的写法,有点难理解,函数包装器的作为是对一个函数进行包装,返回另外一个函数。

在包装的过程中,对旧函数和传递的参数进行改造加工。一般模式是:

// oldF  旧函数, newF 新函数,callback回调函数 options 参数
newF = function(oldF,callback, options) {
    return function(){
        // 在调用newF是,获取newF的参数
        var args = Array.prototype.slice(arguments);
        // this为newF运行的环境
        callback.apply(this,args);
    }  
}
newF(x1,x2)

在express源码中,有如下函数进行包装了:

// restore obj props after function
function restore(fn, obj) {
  var props = new Array(arguments.length - 2);
  var vals = new Array(arguments.length - 2);

  for (var i = 0; i < props.length; i++) {
    props[i] = arguments[i + 2];
    vals[i] = obj[props[i]];
  }

  return function(err){
    // restore vals
    for (var i = 0; i < props.length; i++) {
      obj[props[i]] = vals[i];
    }
    return fn.apply(this, arguments);
  };
}

还有:

done = wrap(done, function(old, err) {
      if (err || options.length === 0) return old(err);
      sendOptionsResponse(res, options, old);
});
// wrap a function
function wrap(old, fn) {
  return function proxy() {
    var args = new Array(arguments.length + 1);

    args[0] = old;
    for (var i = 0, len = arguments.length; i < len; i++) {
      args[i + 1] = arguments[i];
    }

    fn.apply(this, args);
  };
}
// send an OPTIONS response
function sendOptionsResponse(res, options, next) {
  try {
    var body = options.join(‘,‘);
    res.set(‘Allow‘, body);
    res.send(body);
  } catch (err) {
    next(err);
  }
}

 

函数包装器