问题描述
有没有办法让调试器在某个对象或对象的某个属性发生变化时暂停?
watch()
已被弃用。建议(参见 here 和 here)改为使用 setter 和 getter 或 Proxy
objects。
但是 Proxy
对象可以用于此目的的精确度如何?我是否必须在代码中的任何地方通过其代理替换某个对象,即无法按原样和立即调试预先存在的代码?
上述使用 setter 和 getter 的方法是否相同?
breakOn()
(参见 here)似乎只在 HTML 元素发生变化时中断,而不是 JavaScript 对象。
解决方法
我是否必须在代码中的任何地方通过其代理替换某个对象,即无法按原样和立即调试预先存在的代码?
这可能是最简单的,但不是唯一的选择。
如果您确切地知道哪个对象,即您有对它的引用,您可以用 getter/setter 替换它的属性:
const obj = { abc: 123 };
function watchProperty(obj,key) {
const desc = Object.getOwnPropertyDescriptor(obj,key);
let value = desc.value;
Object.defineProperty(obj,key,{
enumerable: desc.enumerable,get() {
console.log('GET',key);
if (desc.writable === undefined) {
if (desc.get) return desc.get.call(obj);
return undefined;
} else {
return value;
}
},set(val) {
console.log('SET',val);
if (desc.writable === undefined) {
if (desc.set) desc.set.call(obj,val);
} else if (desc.writable) {
value = val;
}
},});
}
watchProperty(obj,'abc');
console.log('obj.abc:',obj.abc);
obj.abc = 456;
console.log('obj.abc:',obj.abc);
基于 ECMAScript 2022 specification。
请注意,为了能够使用 Object.defineProperty
,对象不应已经将 configurable
设置为 false
来定义该属性。幸运的是,这只有在首先使用 Object.defineProperty
时才会发生。
我使用了 Object.getOwnPropertyDescriptor
并使该属性的行为特定于 obj
。如果您的对象具有继承的属性,则必须在原型链中更改它,但是使用我的 watchProperty
实现会导致一些奇怪的交互,因为 value
和 obj
是obj
特定。
这也让我想到了另一点:如果您想查看类的一个(或每个)实例,您可以查看原型上的属性。