Почему Object.observe() не предоставляет путь изменения данных для обратного вызова?

Изменения массива Object.observe() обратный вызов содержит объекты со следующими четырьмя свойствами:

  • название
  • объект
  • тип
  • OldValue

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/observe

Почему нет path предоставлено изначально? Пример:

var ob = {
    foo: [
        {moo: "bar", val: 5},
        {val: 8}
    ]
}

ob.foo[0].val = 1;
// callback should provide path "foo.0.val" or "foo[0].val"

Есть модуль Node.js, который расширяет Object.observe() также включить путь: seen.js,
но я переживаю за прирост производительности родного observe() будет потеряно (если нет, не могли бы вы объяснить, как это реализовано?). Возможно, модуль можно будет просмотреть, но не могу представить, что он будет работать хорошо в синхронной среде, и я все еще удивляюсь, почему, кажется, никто не задумывался о дополнительном path имущество.

1 ответ

Решение

Потому что нет четкого пути.

Учтите следующее:

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"

Приведенный выше код не является производственным качеством, используйте его на свой страх и риск.

Другие вопросы по тегам