在代理处理程序中,如何取消获取属性(var)与调用方法? [英] In the Proxy handler, how to distiguish getting a property (var) vs calling a method?

查看:92
本文介绍了在代理处理程序中,如何取消获取属性(var)与调用方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have the following code, where I'm using Proxy object (proxy) to try to catch method calls and access of the properties:

示例: https://jsfiddle.net/r8j4fzxL/2/

(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('get called: ',
                'target:', target,
                'prop:', prop,
                'receiver:', receiver
            );
            //this is OK, if we are called as a method.
            //but it isn't when called as .prop - because, obviously, we return a function here.
            return function(...args) {
                console.log('wrapper args:', args);
                return 42;
            }
        },


    };


    let p1 = new Proxy(X, proxy);
    //how to distinguish the two in the above proxy:
    console.log(p1.test('some arg passed'));
    console.log(p1.test);
})();

我在这里有两个问题。


  1. 一般来说,如果我想同时捕获属性访问权限和方法访问权限,这是正确的方法吗?或者也许我应该以某种方式使用.apply陷阱(虽然没有这样做)?

  1. Generally, is this the right way, if I want to trap both properties access and method access? Or maybe should I go with .apply trap somehow (failed to do so though)?

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

If this is the right way (using .get) - then how do I know how the user accessed the... thing? Via .foo; or via .foo();?

我使用的资源显然并不完全明白:

Resources I used and apparently didn't fully understand:

  • MDN docs: Proxy
  • MDN docs: handler.get()
  • MDN docs: handler.apply()

SO:< a href =https://stackoverflow.com/questions/10226064/javascript-equivalent-of-php-call> PHP等效的PHP __call

推荐答案

代理本质上是一种对象,它暴露出一种编程方式来挂钩对象可以运行的操作ave对他们进行了表演。以此为基础,无法在访问属性时将属性访问与属性访问+调用区分开来。返回值是函数的事实就是您可以知道的。

Proxies are essentially objects that expose a programmatic way to hook into the operations that objects can have performed on them. With that as a base, there is no way to distinguish a property access from a property access + call, at the point where the property is accessed. The fact that the returned value is a function is all that you can know.

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

From the standpoint of the language, p.foo() breaks down into

var p = ...
var foo = p.foo;
foo.apply(p, []);

为例。 p.foo 实际上不会访问 .apply ,但重点是属性访问完全独立于如何实际使用/调用返回的值。

as an example. p.foo wouldn't actually access .apply, but the point is that the property access is entirely independent of how the returned value is actually used/called.

所以你的选择主要是检查 test的值是否已经是一个函数,如果是这样,请用您的包装器包装该值。如果它不是一个函数,你似乎想要跳过它。例如

So you option would essentially be to check whether the value of test was already a function, and if so, wrap that value with your wrapper. If it was not a function, it seems like you'll want to skip wrapping it. 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;
  }
}

这篇关于在代理处理程序中,如何取消获取属性(var)与调用方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆