2

我想了解为什么无法使用 ES6 创建“通用”转发代理。“通用”是指代理目标可以是具有相同代理声明(构造函数 + 处理程序)的任何类型的非原始值(包括函数)。

情况1:

var o = function myCtor() {}

var p = new Proxy({}, {
    construct: function(target, ...args) {
        return Reflect.construct(o, ...args);
    }
});

console.log(new p); // TypeError: p2 is not a constructor

案例2:

var o = {}

var p = new Proxy(function() {}, {
    ownKeys: function(target) {
        return Reflect.ownKeys(o);
    }
});

console.log(Object.keys(p)); // TypeError: 'ownKeys' on proxy: trap result did not include 'arguments'

当我使用 function(){} 作为代理目标(而不是 {})时,案例 1 可以正常工作,但是案例 2 不再有效。

谢谢你的帮助。

4

1 回答 1

1

一个 Proxy 实例是一个目标,所以比较 (proxy instanceof == target.constructor) 将始终返回 true。所以对代理进行操作必须像目标对象类型一样。

  1. 在情况 1,代理返回 Object 的实例,是一个实例但不是 is-a Function 实例,因此不能使用关键字调用。因此new您可以通过传递 Function 的实例来通过测试。

     var o = function myCtor() {}
    
        var p = new Proxy(function(){}, {
            construct: function(target, ...args) {
                return Reflect.construct(o, ...args);
            }
        });
    
        console.log(new p);
    
  2. 在情况 2 中,因为函数具有不可配置的prototype属性并且代理必须是函数实例。所以通过测试 handler.ownKeys() 必须存在prototype属性名称。以及定义为 handler.ownkeys 的任何Object.defineProperty(foo, 'foo', {configurable: false})属性() 必须存在。例如:必须包含可枚举的名称 include foo

    var o = {prototype:{}}
    
    var p = new Proxy(function() {}, {
        ownKeys: function(target) {
            return Reflect.ownKeys(o);
        }
    });
    
    console.log(Object.keys(p));
    

这里有很多代理示例,您可以自己品尝这些示例。品尝后您还可以深入了解代理文档。

于 2017-02-28T19:55:30.950 回答