因为没有明确的道路。
考虑以下:
var movall = {moo: "bar", val: 5};
var ob1 = {a: mooval};
var ob2 = {b: movall};
现在假设我观察到movall
。然后我更新moo
. 路径是什么?是movall.moo
,还是ob1.a.moo
,还是ob2.b.moo
?如果我观察到ob1
,则没有报告任何更改,因为它的任何属性都没有更改(更改是其属性之一的内部更改,这不算数)。
对象独立于嵌套在其他对象中的存在。它们可以嵌套在多个其他对象中。没有唯一的“路径”来描述如何从潜在的多个起点向下到可能已更改的特定属性。
JS 也不知道您到达被更改属性的路径。因此,在 中ob.foo[0].val = 1;
,JS 只是评估链,到达foo[0]
对象,更改其val
属性,此时不知道它是如何到达的foo[0]
。它所知道的只是foo[0]
情况发生了变化。它在 内部发生了变化,但它也可能在碰巧作为属性的ob
其他对象中发生了变化。foo[0]
但是,您可以通过在低级观察/通知机制之上构建一些机制来实现您似乎想要实现的目标。我们将在一个对象上定义一个函数,该函数在其属性对象上设置观察者,以此类推,并使用正确构造的路径将更改记录传播回来:
function notifySubobjectChanges(object) {
var notifier = Object.getNotifier(object); // get notifier for this object
for (var k in object) { // loop over its properties
var prop = object[k]; // get property value
if (!prop || typeof prop !== 'object') break; // skip over non-objects
Object.observe(prop, function(changes) { // observe the property value
changes.forEach(function(change) { // and for each change
notifier.notify({ // notify parent object
object: change.object, // with a modified changerec
name: change.name, // which is basically the same
type: change.type,
oldValue: change.oldValue,
path: k +
(change.path ? '.' + change.path : '') // but has an addt'l path property
});
});
});
notifySubobjectChanges(prop); // repeat for sub-subproperties
}
}
(注意:change
对象被冻结了,我们不能添加任何东西,所以我们必须复制它。)
现在
a = { a: { b: {c: 1 } } }; // nested objects
notifySubobjectChanges(a); // set up recursive observers
Object.observe(a, console.log.bind(console)); // log changes to console
a.a.b.c = 99;
>> 0: Object
name: "c"
object: Object
oldValue: 1
path: "a.b" // <=== here is your path!
type: "update"
上述代码不是生产质量的,使用风险自负。