Потому что нет четкого пути.
Рассмотрим следующее:
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"
Приведенный выше код не является производственным, используйте его на свой страх и риск.
person
Community
schedule
06.11.2014