包装具有属性的JavaScript函数

时间:2019-02-08 04:59:30

标签: javascript node.js

我正在尝试包装request节点模块以为每个请求添加一条日志语句。通常,这很简单:

function wrapper(...args) {
  console.log('Hello');
  return request(...args);
};

但是,request函数具有我也需要的诸如request.defaults之类的属性。一个人怎么可能只包装函数但保留属性而不更改request API?

2 个答案:

答案 0 :(得分:1)

可能您应该返回request函数本身而不执行它-

function wrapper() {
   console.log('logs');
   return request;
}


wrapper()('http://sample.com', (err, rsp, body) => {

   //do something
})

wrapper().defaults({});    //calling the default method

答案 1 :(得分:1)

这里有两个想法,用于包装现有函数,同时保留要包装的函数的属性:

将属性复制到新功能

首先,我们创建一个包装request的新函数。然后,我们使用Object.assign()将属性从request复制到wrappedRequest

function wrappedRequest(...args) {
    console.log('called request!');
    return request(...args);
};

Object.assign(wrappedRequest, request); // copy properties from request to wrappedRequest

这里要记住的是,您只复制一次一次属性。在此语句之后修改或添加的任何属性都不会添加到新函数中。


ES2015 Proxy()

如果可用,这是首选方式。它允许您捕获函数调用,属性获取器和属性设置器,即使它们是在创建代理后 之后设置的。

const handler = {
    apply: function(target, thisArg, argumentList) {
        console.log('called request!');
        return target.apply(thisArg, argumentList);
    },
};

const wrappedRequest = new Proxy(request, handler);

handler.apply()截获对wrappedRequest()的任何呼叫。并且默认情况下,代理上的获取和设置属性将镜像目标对象(在本例中为request的获取和设置属性。


进一步阅读