-1

According to the ECMAScript spec, obj.[[Get]] is resolved as follows:

  1. First check whether an object has the key (GetOwnProperty)
  2. If it does not, defer to [[Get]] of obj’s prototype.
  3. […] (other steps omitted)

However, the spec for proxy.[[Get]] performs the following:

  1. […] (some steps omitted)
  2. If the trap is for [[Get]] is missing, defer to target.[[Get]].

This leads to the following inconsistency when combined with getPrototypeOf: an object can be considered an instance of some type T, but have no methods of that type.

Example as follows:

var o = {};
var p = new Proxy(o, { 
  getPrototypeOf(target) { return Array.prototype;} 
});

console.log(p instanceof Array) //true
console.log(p.push) //undefined

Technically this behavior can be fixed by writing a [[Get]] handler, but this will likely push the performance down to unusable levels*.

* Experimenting on a module system inspired by ruby's. This suggests that every module function call will run through 1 or more proxy.[[Get]]s, which cuts performance to at least 1/10. Very crude benchmarks suggest 130× (instantiation) - 500× (function call) performance penalty for my own implementation.

user3840170
  • 26,597
  • 4
  • 30
  • 62
blackening
  • 903
  • 6
  • 14
  • 1
    And what's your question? If you want a discussion of this behavior you might rather write to https://esdiscuss.org . – Felix Kling Feb 03 '17 at 07:50
  • My question was if that behavior was inconsistent. I was not aware that this was not the appropriate place to discuss this. – blackening Feb 03 '17 at 09:20
  • Also note that at least for this example, your object will also fail `Array.isArray(p)`. This could be a slight inconsistency, it's true, but I agree ESDiscuss might be a better place to ask about it. – loganfsmyth Feb 03 '17 at 16:53

1 Answers1

1

I don't believe it's inconsistent per se: you've just discovered one of many "invariants" that proxies allow you to violate. (Scare quotes because it's not one of the invariants in the spec.)

If you want [[Get]]'s behavior to match that implied by [[GetOwnPrototype]], you can as you say write your own handler, or just not put a handler on [[GetOwnPrototype]].

Bakkot
  • 1,175
  • 7
  • 13