首页 > 解决方案 > 使用 javascript 代理跟踪方法调用

问题描述

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

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

标签: javascriptjavascript-objectses6-proxy

解决方案


这是因为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


推荐阅读