2017-02-03 1 views
0

Согласно ecmascript spec, OBJ [[получить]] решается следующим образом:Экстремальный [[Get]] не использует прокси getPrototypeOf - поведение непоследовательно? .

  1. Сначала проверьте, имеет ли объект ключ (getOwnProperty)
  2. Если этого не произойдет, отложить до Object.getPrototypeOf (объект) [[получить]]
    ... (другие шаги опущены)

Однако.для прокси [[получить]] выполняет следующие операции:

... (некоторых шагов опущенных)
7. Если ловушка для [[получить]] отсутствует, отложить до целей . [[get]].

Это приводит к следующей несогласованности в сочетании с getPrototype: объект может быть экземпляром некоторого типа T, но не имеет методов такого типа.

Пример следующим

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

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

Технически такое поведение можно исправить, написав [[получить]] обработчик, но это, скорее всего, толчок производительности вплоть до непригодных уровней * ,

* Экспериментируйте на модульной системе, вдохновленной рубином. Это говорит о том, что каждый вызов функции модуля будет выполняться через 1 или более прокси. [[Get]] s, что снижает производительность не менее 1/10.

Редактирование: очень грубые тесты предлагают 130x (экземпляр) - штраф в размере 500x (функциональный вызов) для моей собственной реализации.

+0

И каков ваш вопрос? Если вы хотите обсудить это поведение, скорее всего, вы можете написать https://esdiscuss.org. –

+0

Мой вопрос был в том, что это поведение было непоследовательным. Я не знал, что это не подходящее место для обсуждения этого. – blackening

+0

Также обратите внимание, что, по крайней мере, для этого примера, ваш объект также будет терпеть неудачу «Array.isArray (p)». Это может быть небольшая несогласованность, это правда, но я согласен, что ESDiscuss может быть лучшим местом, чтобы спросить об этом. – loganfsmyth

ответ

1

Я не считаю, что это противоречиво: вы только что обнаружили один из многих «инвариантов», которые прокси позволяют вам нарушать. (Исправляет котировки, потому что это не один из invariants в спецификации.)

Если вы хотите, чтобы поведение [[Get]] соответствовало тому, что подразумевалось в [[GetOwnPrototype]], вы можете, как вы говорите, написать собственный обработчик , или просто не помещать обработчик на [[GetOwnPrototype]].

+0

Спасибо. Спектр кажется неожиданно редким в отделе инвариантов. – blackening