Предупреждение: обычно, при возможности, вам следует избегать использования 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.