Потому что нет четкого пути.
Рассмотрим следующий пример:
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"
Приведенный выше код не является производство качественной, используйте на свой страх и риск.
Хорошо, но как 'Object.observe()' ведет себя в конкретной ситуации, которую вы описали? Если два других объекта содержат первый объект, произойдет 3 изменения событий? Новый объект передается обратному вызову, поэтому наследование/вложение объектов не будет проблемой. BTW: «путь» не должен содержать «movall», «ob» или «ob2», но только следующее. В сочетании с переданным объектом, сменой 'type' и' oldValue', можно было бы непосредственно создать операцию OT. – CoDEmanX
Изменение событий происходит, только если они наблюдаются, как дерево, падающее в лесу. Поэтому, если мы также наблюдаем «ob2», то да, другое событие изменения будет отправлено этому наблюдателю. –
Просто уточнить: если мы наблюдаем 'movall' и' ob2', 'ob2' содержит' movall', и я делаю замену на 'ob2' -' ob2.b.movall.moo = "foo" '- будет там быть одним событием смены для «movall» и «ob2»? Если да, то нет никакой двусмысленности пути, поскольку это было бы относительно объекта, который мы наблюдаем, независимо от вложенных объектов ('moo' для' movall' и 'b.movall.moo' для' ob2'). – CoDEmanX