Ошибки прокси функции .toString()

Я пытаюсь вызвать .toString() на прокси-сервере функции.

Простое создание прокси-сервера функции и вызов toString вызывает «TypeError: Function.prototype.toString не является универсальным», установка toString для возврата источника исходных причин «RangeError: превышен максимальный размер стека вызовов», но создание ловушки получения для toString работает.

Почему простая установка функции toString не работает, а ловушка get работает?

function wrap(source) {
 return(new Proxy(source, {}))
}
wrap(function() { }).toString()

function wrap(source) {
 let proxy = new Proxy(source, {})
 proxy.toString = function() {
  return(source.toString())
 }
 return(proxy)
}
wrap(function() { }).toString()

function wrap(source) {
 return(new Proxy(source, {
  get(target, key) {
   if(key == "toString") {
    return(function() {
     return(source.toString())
    })
   } else {
    return(Reflect.get(source, key))
} } })) }
wrap(function() { }).toString()


person Daniel Herr    schedule 08.07.2016    source источник
comment
связанные: esdiscuss.org/topic/   -  person tybro0103    schedule 08.11.2017
comment
Не связано: return — это ключевое слово, а не функция сама по себе, поэтому это return x, а не return(x). Парни здесь ничего не делают.   -  person Albin    schedule 24.02.2018


Ответы (2)


У меня была такая же проблема. Наконец-то я понял, что это проблема с this. Добавьте ловушку get в свой обработчик, привяжите проксируемый объект как this к прокси-свойству, если это function, и, похоже, все работает нормально:

function wrap(source) {
    return new Proxy(source, {
        get: function (target, name) {
            const property = target[name];
            return (typeof property === 'function') 
                ? property.bind(target)
                : property;
        }
    });
}

console.log(wrap(function () {}).toString());

person Steve Kehlet    schedule 25.02.2017

TypeError: Function.prototype.toString не является универсальным

Похоже, Function.prototype.toString не должен вызываться Proxy.

proxy.toString = function() {

Это назначение прокси передается объекту source, так как у вас нет ловушки для назначения. Если вы отметите source.hasOwnProperty('toString'), вы получите true. Когда вы добавляете ловушку get, вы не меняете метод toString и не добавляете его в объект source, поэтому он работает.

Другим возможным решением является

function wrap(source) {
  let proxy = new Proxy(source, {})
  proxy.toString = Function.prototype.toString.bind(source)
  return proxy
}
person Qwertiy    schedule 11.07.2016