我想使用代理(我没有制作的游戏中的对象)观察一个对象。我发现这是另一个问题的答案:
var proxied = new Proxy(foo, {
get: function(target, prop) {
console.log({
type: "get",
target,
prop
})
return Reflect.get(target, prop)
},
set: function(target, prop, value) {
console.log({
type: "set",
target,
prop,
value
})
return Reflect.set(target, prop, value)
}
})
如果更改它,我必须做proxied.bar = "Hello world"
。但是我没有改变,游戏却改变了。而且它不会像这样(它确实foo.bar
= ...,他们不使用代理...)那么,我该怎么做才能观察数组?
谢谢。
答案 0 :(得分:0)
没有太多选择可以观察对象是否已更改。以前我们可以使用Object.observe()
或Object.watch()
,但是这两个都已被弃用,不再可靠。
代理是唯一的选择,但是显然游戏必须使用代理对象才能使陷阱被命中。
就操作原始foo
对象而言,我并不完全知道您能做什么,但是将proxied
设置为指向它的对象,而不是创建您的foo
对象自己代理的自我。换句话说,
foo = new Proxy(foo, {
get: function(target, prop) {
console.log({
type: "get",
target,
prop
})
return Reflect.get(target, prop)
},
set: function(target, prop, value) {
console.log({
type: "set",
target,
prop,
value
})
return Reflect.set(target, prop, value)
}
})
如果您可以像这样直接操纵游戏对象,则可以在get
和set
陷阱中传递自己的回调函数,并观察该对象的任何变化。
您可能无法重新分配foo
(如果它是用const
声明的)。在这种情况下,可以解决此问题,但是它有点笨拙且不像上述方法那样同步。
基本上,您可以创建一个函数,该函数在foo
对象中创建条目的缓存,并以给定的间隔重新检查foo
是否有任何更改,并执行您指定的任何回调逻辑。我不能太具体,因为实现细节确实取决于foo
的结构( eg ,其嵌套性以及它可能包含的对象的类型-它们是日期,函数引用,或许多其他类型的对象)。
基本实现可能如下所示:
foo = { ... } // whatever kind of object foo is
function observeFoo() {
const entries = Object.entries(foo);
// initialize cache if we don't have one
if (!observeFoo.cache) observeFoo.cache = {};
// begin checking keys in cache
entries.forEach(entry => {
const [ key, value ] = entry;
if (observeFoo.cache[key] !== value) {
// do something regarding this change
}
// update cache
observeFoo.cache[key] = value;
});
}
setInterval(observeFoo, 1000);