Реагируйте на изменения с помощью Object.observe

Alex Danilo

Многим фреймворкам JavaScript, использующим MVC или MDV, необходимо реагировать на изменения объектов, моделирующих состояние внутри веб-приложения. Эта возможность является фундаментальной частью модели привязки данных.

Существует множество различных способов мониторинга объектов JavaScript и свойств DOM для запуска каких-либо действий, но большинство методов не идеальны по различным причинам, таким как производительность и т. д.

Чтобы повысить производительность веб-приложений, TC39 — органу по стандартизации, курирующему разработку ECMAScript (JavaScript), был предложен новый метод под названием Object.observe() .

Object.observe() позволяет добавить прослушиватель к любому объекту JavaScript, который вызывается всякий раз, когда этот объект или его свойства изменяются.

Вы можете попробовать это прямо сейчас в Chrome Canary версии 25.

Чтобы поэкспериментировать с этой функцией, вам необходимо включить флаг «Включить экспериментальный JavaScript» в Chrome Canary и перезапустить браузер. Флаг можно найти в разделе «about:flags», как показано на изображении ниже:

Хромированные флаги.

Вот простой пример того, как настроить наблюдателя на объекте:

var beingWatched = {};
// Define callback function to get notified on changes
function somethingChanged(changes) {
    // do something
}
Object.observe(beingWatched, somethingChanged);

Когда объект «beingWatched» изменяется, он запускает функцию обратного вызова «somethingChanged», которая получает массив изменений, примененных к объекту.

Таким образом, движок JavaScript может буферизовать ряд изменений и передать их все за один вызов функции обратного вызова. Это помогает оптимизировать обратные вызовы, чтобы ваш код мог выполнять множество манипуляций с JavaScript, но обрабатывал лишь несколько обратных вызовов, группируя обновления вместе.

Функция обратного вызова будет срабатывать всякий раз, когда свойство добавляется, изменяется, удаляется или перенастраивается.

Еще одна приятная вещь при наблюдении за массивами заключается в том, что если в массив было внесено несколько изменений, вы можете использовать вспомогательную библиотеку Change Summary для создания минимального набора изменений, чтобы клиентскому JavaScript не приходилось вручную сканировать массив. массив для проверки каждого элемента.

Вы можете довольно легко перебрать каждое изменение, выполнив в своей функции обратного вызова «somethingChanged» что-то вроде следующего:

function whatHappened(change) {
    console.log(change.name + " was " + change.type + " and is now " + change.object[change.name]);
}
function somethingChanged(changes) {
    changes.forEach(whatHappened);
}

Свойство type определяет, что произошло с объектом. Некоторые примеры устанавливаемых свойств и связанного типа можно увидеть в приведенном ниже коде.

beingWatched.a = "foo"; // new
beingWatched.a = "bar"; // updated
beingWatched.a = "bar"; // no change
beingWatched.b = "amazing"; // new

Самое замечательное в этом методе то, что все возможности мониторинга находятся внутри движка JavaScript, что позволяет браузеру хорошо оптимизировать его и освободить ваш JavaScript для реализации функций, использующих преимущества этой функции.

Еще одна замечательная функция для разработки — возможность использовать Object.observe() для запуска отладчика при каждом изменении объекта. Для этого вы должны использовать код, подобный примеру ниже.

Object.observe(beingWatched, function(){ debugger; });

Вот отличное видеообращение к Object.observe(), в котором оно подробно объясняется.

Также имеется хорошее описательное описание и рабочий пример здесь .

Орган по стандартизации TC39 хочет получить отзывы об этой функции, поэтому попробуйте ее и дайте нам знать, что вы думаете.