let ar = [];
let p = new Proxy(new Map(), {
get: (o, k) => {
ar.push(1)
return Reflect.get(o, k).bind(o)
},
set: (o, k, v) => {
ar.push(2)
return Reflect.set(o, k, v)
}
});
p.set(1, 2)
p.get(1)
console.log(ar) //Outputs [1,1]
Я пытаюсь перехватить операции set и get для объекта Map. Я никоим образом не пытаюсь расширить/подклассировать карту. В процессе проксирования указанного объекта Map я столкнулся с этим странным неожиданным поведением: ловушка set не срабатывает в приведенном выше коде, но вместо этого ловушка get срабатывает дважды!
Далее я продолжил регистрировать значения k(key) из ловушки get следующим образом;
//same code above
get: (o, k) => {
console.log(k) //Logs set and then get!
return Reflect.get(o, k).bind(o)
}
//same code below
Я ожидаю, что массив будет [2,1]
и console.log(k)
в ловушке get, чтобы фактически вывести значение ключа.
Я хочу знать, почему это происходит именно так, я столкнулся с парой подобных проблем, связанных с проксированием карт, ни одна из них не привела к каким-либо разумным рассуждениям о том, почему это происходит.
Моя конечная цель — запустить событие в установленной ловушке. Использую ли я прокси для чего-то, для чего он предназначен? Если нет, то какой подход мне следует выбрать? Должен ли я отказаться от использования карты в литерал объекта, даже если это принесет все минусы его использования? пример: нет свойства длины, свойства только для строки, нет принудительно-уникальных ключей и т. д.
ОБНОВЛЕНИЕ: чем больше я копаюсь в этой проксированной карте, тем больше проблем у меня возникает. Теперь мне кажется, что ES6 Proxy API обрабатывает Карты так же, как и обычный объект. Ответ Вилл и мои раскопки подтверждают это. Почему я говорю это? Прочтите следующее;
//same code above
get: (o, k) => {
if(k === 'tray') return ']'
return Reflect.get(o, k).bind(o)
}
//same code below
p.tray //returns ]
Приведенный выше код теоретически не должен работать, верно? Как будто Proxy использует ту же логику для перехвата операций с объектами при перехвате Maps! В виде;
///--While the following---//
let m = new Map();
m.set('tray', ']')
m.tray //undefined
В ответе Вила говорится, что прокси-сервер идентифицирует Map.prototype.set
как первое чтение set и затем вызывает его как функцию. Разве это не означает, что ловушка set, которую я написал в исходном коде (в самом верху), не перехватывает модификацию/установку свойства карты, и фактически вместо этого используется неявный/собственный для Map-Map.prototype.set
из Reflect.set
, которые мы предоставляем через прокси?
Разве все это не подтверждает тот факт, что прокси и карты плохо сочетаются друг с другом? Я иду по неправильному пути? Что я неправильно понимаю, если это так? Должны ли прокси относиться к картам как к любому другому объекту?