2

I would like to understand why it is not possible to create an "universal" forward proxy with ES6. By "universal" I mean that the proxy target may be any kind of non-primitive value (including function) with the same proxy declaration (constructor + handlers).

case 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

case 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'

Case 1 works properly when I use function(){} as Proxy target (instead of {}) but then, case 2 do not works any more.

Thanks for your help.

Franck Freiburger
  • 26,310
  • 20
  • 70
  • 95
  • Functions have the following properties: `length`, `name`, `arguments, `caller` and `prototype`. It seems that a proxy that wraps a function expects `arguments` to be in the list of keys. There might be others, but fixing this would be as simple as `return ['arguments', ...Reflect.ownKeys(o)]`. – Felix Kling Feb 28 '17 at 20:02
  • @FelixKling cheater ! :) – Franck Freiburger Feb 28 '17 at 20:06
  • 2
    See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/ownKeys#Invariants : *"The result List must contain the keys of all non-configurable own properties of the target object."* – Felix Kling Feb 28 '17 at 20:07
  • 2
    The behavior you are observing is the result of Proxies preserving the [Invariants of the Essential Internal Methods](https://tc39.github.io/ecma262/#sec-invariants-of-the-essential-internal-methods) in ECMAScript. – evilpie Feb 28 '17 at 20:08
  • @FelixKling can you explain why "The result List must contain the keys of all non-configurable own properties of the target object."? I want to use a proxy to make an array (the target) appear to be an object by using a map of array indexes to field names in the proxy handler. I certainly have no reason for the ownKeys method to return length as a property, why does ECMA script have this requirement? I want ownKeys() to simply return the list of field names from the field/index map (without having to include "length" - unless that is the name of one of the fields). – Casey May 07 '19 at 05:27

1 Answers1

1

an Proxy instance is-a target,so to compare (proxy instanceof == target.constructor) will always return true.so operate on an proxy must be like as the target object type.

  1. in case 1,a Proxy return an instance of Object,is an instance but not is-a Function instance so that can't be called with new keyword.so you can pass the test by pass an instance of Function instead.

     var o = function myCtor() {}
    
        var p = new Proxy(function(){}, {
            construct: function(target, ...args) {
                return Reflect.construct(o, ...args);
            }
        });
    
        console.log(new p);
    
  2. in case 2,because the Function have an un-configurable prototype property and the proxy must be is-a Function instance.so by pass the test the handler.ownKeys() must exist the prototype property name.and any property defined as Object.defineProperty(foo, 'foo', {configurable: false}) the handler.ownkeys() must be exist it.e.g:must include enumerable names include foo.

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

there is a lot of proxy example here,you can taste these examples by yourself.after tasted you also could see proxy documentation in depth.

holi-java
  • 29,655
  • 7
  • 72
  • 83
  • Proxy can intercept any object,and the function is an instance Function object too.but they have some different usages.in the function way the proxy created must call as a function,in the object way the proxy must use as an object. etc. – holi-java Feb 28 '17 at 20:02
  • Functions are objects. Also you can [edit] your answer. – Felix Kling Feb 28 '17 at 20:03