使用javascript代理跟踪方法调用

时间:2018-08-23 22:06:52

标签: javascript javascript-objects es6-proxy

var handler1 = {
     get:function(target,key){
         if (typeof target[key] == "function"){
             var method = Reflect.get(target, key);
             return method.bind(target);
         }
     }
}
var handler2 = {
    get: function(target, key){
          if (typeof target[key] == "function"){
            return function(...args){
               var method = Reflect.get(target, key);
               return method.apply(target, args);
            }
          }
     }
}
var proxyObject = new Proxy(window, handler1);
window.obj = function(){console.log("function invoked")};
window.obj.prop = 3; 
var o = proxyObject.obj;
o()// prints "function invoked"
console.log(o.prop) // returns undefined

两个处理程序的拦截方法调用都很好,但是在此过程中,方法对象上的任何属性都会丢失。有没有办法绑定正确的上下文并在代理返回的对象中保留方法属性。

1 个答案:

答案 0 :(得分:0)

这是因为bind创建了一个与原始函数不同的全新函数:

function foo(a, b) { return a + b; };

var bar = foo.bind({});

console.log(foo === bar);

因此在您的处理程序中,无需返回绑定函数,只需返回原始函数:

var handler = {
    get:function(target,key){
        if (typeof target[key] == "function") {
            return Reflect.get(target, key);                       // return the original function
        }
    }
}

var proxyObject = new Proxy(window, handler);
window.obj = function() { console.log("function invoked"); };
window.obj.prop = 3;

var o = proxyObject.obj;
o()                                                                // prints "function invoked"
console.log(o.prop)                                                // returns 3
console.log(o === window.obj);                                     // true