В настоящее время я пишу инструмент, который отслеживает изменения, внесенные в объект с использованием прокси. Поэтому у меня есть функция watchObject
которая принимает объект в качестве аргумента и обертывает его внутри прокси- watchObject
, где обработчики, соответствующие изменениям в debugger;
вызова объекта debugger;
, Этот watchObject
в основном основан на принятом ответе на этот вопрос.
Настройка ловушек на обработчиках get, defineProperty и deleteProperty работает очень хорошо, когда объект только модифицируется.
Однако, когда ссылка заменена, обработчики не вызываются и обход вокруг нее прокси-сервера теряется.
Давайте рассмотрим объект a
содержащий ключ foo
: var a = { foo: "bar"};
Например, следующее вызовет точку останова отладчика, которая находится внутри моих ловушек:
a.foo = "Hello"
delete a.foo
a.baz = "Hi"
... Но называть это потом: a = {keyOne: "one"}
не будет вызывать a = {keyOne: "one"}
останова и последующие вызовы вышеприведенных примеров (которые в противном случае запускают точку останова) больше не будут вызывать точку останова.
Поэтому я хотел бы знать, есть ли способ обнаружить такую операцию, как: a = {keyOne: "one"}
выполняется так, чтобы отслеживать изменения ссылки для переменной и иметь возможность воссоздать прокси-объект на новом ссылочном объекте,
Кроме того, поскольку весь процесс мониторинга изменений объекта нацелен на облегчение отладки, решение должно быть не разрушительным в коде, который задействован.
Использование прокси-сервера велико, поскольку оно только перехватывает и не изменяет общего поведения обернутого объекта.
Я хочу это сделать...
Похоже, вы хотите поймать сам объект, а не метод.
Поскольку объектная переменная будет установлена как свойство окна или другого объекта, мы можем использовать функцию для определения геттера и сеттера в окне (или этом объекте) с именем требуемой переменной:
function trackedProxy(name, val, _this){
let handler = {} // place your property traps here
let _privateObject = val
let _privateProxy = new Proxy(_privateObject, handler)
Object.defineProperty(_this, name, {
get: function() {
return _privateProxy;
},
set: function(value) {
console.log("object changed")
// Do something
return _privateObject = value;
}
});
}
//build one with invocation of the function, but do not set as equal to a var or you will have the same issue.
//**bad! - var a = trackedProxy('a',{keyOne: "one"},this)
trackedProxy('a',{ foo: "bar"}, this)
console.log(a)
//Proxy{ foo: "bar"}
a={keyOne: "one"}
//Object changed
console.log(a)
//Proxy{keyOne: "one"}
Имейте в виду, что после этого вы не можете переопределить свойство в окне.
Надеюсь, это поможет :)