Javascript 在代理处理程序中,如何区分获取属性(var)和调用方法?

Javascript 在代理处理程序中,如何区分获取属性(var)和调用方法?,javascript,ecmascript-6,Javascript,Ecmascript 6,我有以下代码,其中我使用代理对象(Proxy)尝试捕获方法调用和属性访问: 例如: 我这里有两个问题 通常,如果我想同时捕获属性访问和方法访问,这是正确的方法吗?或者也许我应该去。以某种方式应用陷阱(尽管失败了) 如果这是正确的方法(使用.get)-那么我如何知道用户是如何访问。。。事情通过.foo或通过.foo() 我使用的资源,显然没有完全理解: 因此:代理本质上是一种对象,它公开了一种编程方式,以钩住对象可以对其执行的操作。以此为基础,无法在访问属性的位置区分属性访问和属性访问+

我有以下代码,其中我使用代理对象(Proxy)尝试捕获方法调用和属性访问:

例如:

我这里有两个问题

  • 通常,如果我想同时捕获属性访问和方法访问,这是正确的方法吗?或者也许我应该去。以某种方式应用陷阱(尽管失败了)

  • 如果这是正确的方法(使用.get)-那么我如何知道用户是如何访问。。。事情通过
    .foo或通过
    .foo()

  • 我使用的资源,显然没有完全理解:


    因此:

    代理本质上是一种对象,它公开了一种编程方式,以钩住对象可以对其执行的操作。以此为基础,无法在访问属性的位置区分属性访问和属性访问+调用。返回值是函数这一事实是您所能知道的全部

    从语言的角度来看,
    p.foo()

    var p = ...
    var foo = p.foo;
    foo.apply(p, []);
    
    举个例子
    p.foo
    实际上不会访问
    .apply
    ,但关键是属性访问完全独立于返回值的实际使用/调用方式

    因此,您的选项本质上是检查
    test
    的值是否已经是一个函数,如果已经是,则用包装器包装该值。如果它不是一个函数,那么您似乎希望跳过包装它。e、 g

    get: function(target, prop, receiver) {
      var value = Reflect.get(target, prop, receiver);
      if (typeof value === "function") {
        return function(...args) {
          // probably call 'value' with whatever you need
        };
      } else {
        // return the origin value.
        return value;
      }
    }
    

    这实际上是这个问题的一个解决方案(它被标记为此问题的副本,但不是!!):

    您无法在“get”陷阱中获取参数,因为当调用get陷阱时,函数还没有被调用
    但您可以使用“应用”陷阱创建另一个代理,示例如下:

    (function() {
        'use strict';
        console.clear();
    
        //some empty class where I want to trap methods & props
        class X {
    
        }
    
        let proxy = {
            get: function(target, prop, receiver) {
                console.log(arguments);//this gives the arguments of the 'get' trap itself. 
    
    
            // normally you trap an existent funcion, in this example we are creating a new one here
            var F = function(...args){
                console.log('Original function call', args);
            }
    
            return new Proxy(F, {
                    apply: function(target, thisArg, argumentsList) {
                // here you have the arguments
                console.log('Trapped function call', argumentsList);
                            return target.apply(thisArg, argumentsList);                        
                    }});
    
            },
    
    
        };
    
    
        let p = new Proxy(X, proxy);
        console.log(p.test('some arg passed'));
    
    })();
    

    因此,诀窍是使用get first捕获函数,而不是返回原始函数,而是使用apply trap将代理返回给原始函数。

    谢谢!我想我明白了。但是,要100%理解它:)-如果目标根本没有
    测试,我的任务就是。。。不可能?如果它没有值,您可以根据名称“test”将其硬编码为函数。你永远不会想要一个有时是函数,有时不是的属性。属性的类型不应该根据属性的使用方式而改变,这会让人非常困惑。啊,哇,这很聪明:)谢谢!是的,谢谢你注意到另一个问题不是重复的:)
    
    (function() {
        'use strict';
        console.clear();
    
        //some empty class where I want to trap methods & props
        class X {
    
        }
    
        let proxy = {
            get: function(target, prop, receiver) {
                console.log(arguments);//this gives the arguments of the 'get' trap itself. 
    
    
            // normally you trap an existent funcion, in this example we are creating a new one here
            var F = function(...args){
                console.log('Original function call', args);
            }
    
            return new Proxy(F, {
                    apply: function(target, thisArg, argumentsList) {
                // here you have the arguments
                console.log('Trapped function call', argumentsList);
                            return target.apply(thisArg, argumentsList);                        
                    }});
    
            },
    
    
        };
    
    
        let p = new Proxy(X, proxy);
        console.log(p.test('some arg passed'));
    
    })();