Object.prototype.watch()

Предупреждение: обычно, при возможности, вам следует избегать использования watch() и unwatch(). Эти два метода реализованы только в Gecko, и они, в основном, предназначены только для отладочных целей. Кроме того, использование точек наблюдения серьёзно бъёт по производительности, что особенно заметно при использовании их на глобальных объектах, например window. Обычно вместо них вы можете использовать сеттеры и геттеры или прокси. Для более подробной информации смотрите раздел Совместимость с браузерами. Также, не путайте Object.watch с Object.observe.

Сводка

Метод watch() следит за присваиванием свойству значений и запускает указанную функцию, когда это происходит.

Синтаксис

obj.watch(prop, handler)

Параметры

prop
Имя свойства объекта, чьи изменения вы хотите отслеживать.
handler
Функция, вызывающаяся при изменении значения указанного свойства.

Описание

Следит за присваиваниями свойству prop в этом объекте, вызывая функцию handler(prop, oldval, newval) всякий раз, когда свойство prop устанавливается и сохраняет возвращённое значение в этом свойстве. Точка наблюдения может отфильтровывать (или отменять) присваивание значения, возвращая изменённое новое значение newval (или старое значение oldval).

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

Для удаления точки наблюдения используйте метод unwatch(). По умолчанию, метод watch наследуется каждым объектом, произошедшим от Object.

Отладчик JavaScript имеет функциональность, аналогичную предоставляемой этим методом, а также и другие возможности отладки. Информацию по отладчику можно получить в статье про Venkman.

В Firefox, функция handler вызывает только при присваивании из скрипта, не из встроенного кода. Например, window.watch('location', myHandler) не вызовет myHandler, если пользователь щёлкнет по ссылке с якорем в текущем документе. Однако, выражение window.location += '#myAnchor' вызовет myHandler.

Примечание: вызов watch() на объекте для определённого свойства перезапишет любые ранее назначенные на него обработчики.

Примеры

Пример: использование watch и unwatch

var o = { p: 1 };

o.watch('p', function (id, oldval, newval) {
  console.log('o.' + id + ' изменено с ' + oldval + ' на ' + newval);
  return newval;
});

o.p = 2;
o.p = 3;
delete o.p;
o.p = 4;

o.unwatch('p');
o.p = 5;

Этот скрипт выведет следующее:

o.p изменено с 1 на 2
o.p изменено с 2 на 3
o.p изменено с undefined на 4

Пример: использование watch для проверки свойств объекта

Вы можете использовать watch для проверки присваивания к любым свойствам объекта. Этот пример гарантирует, что каждый человек имеет допустимое имя и возраст между 0 и 200.

Person = function(name, age) {
  this.watch('age', Person.prototype._isValidAssignment);
  this.watch('name', Person.prototype._isValidAssignment);
  this.name = name;
  this.age = age;
};

Person.prototype.toString = function() {
  return this.name + ', ' + this.age;
};

Person.prototype._isValidAssignment = function(id, oldval, newval) {
  if (id === 'name' && (!newval || newval.length > 30)) {
    throw new RangeError('недопустимое имя для ' + this);
  }
  if (id === 'age'  && (newval < 0 || newval > 200)) {
    throw new RangeError('недопустимый возраст для ' + this);
  }
  return newval;
}

will = new Person('Уилл', 29);
print(will);   // Уилл, 29

try {
  will.name = '';
} catch (e) {
  print(e);
}

try {
  will.age = -4;
} catch (e) {
  print(e);
}

Этот скрипт выведет следующее:

Уилл, 29
RangeError: недопустимое имя для Уилл, 29
RangeError: недопустимый возраст для Уилл, 29

Спецификации

Не является частью какой-либо спецификации. Реализована в JavaScript 1.2.

Совместимость с браузерами

  • Этот полифилл предлагает watch для всех совместимых с ES5 браузеров
  • Использование объекта Proxy позволяет вам сделать ещё более глубокие изменения при присваивании свойств
Возможность Chrome Firefox (Gecko) Internet Explorer Opera Safari
Базовая поддержка Нет (Да) Нет Нет Нет
Возможность Android Chrome для Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Базовая поддержка Нет Нет (Да) Нет Нет Нет

Примечание: вызов watch() на объекте Document, начиная с Firefox 23, выбрасывает исключение TypeError (ошибка 903332). Эта регрессия была поправлена в Firefox 27.

Смотрите также

Метки документа и участники

 Внесли вклад в эту страницу: Mingun
 Обновлялась последний раз: Mingun,