Object.prototype.watch()

Застереження: Не використовуйте watch() та unwatch()! Ці два методи були реалізовані лише у Firefox до 58-ї версії, вони застаріли та були прибрані у Firefox 58+. До того ж, використання точок спостереження має серйозний негативний вплив на продуктивність, особливо при використанні на глобальних об'єктах, таких як window. Звісно, ви можете, натомість, використовувати сетери та гетери або проксі.

Метод watch() стежить за присвоєнням властивості значення, та запускає функцію, коли це відбувається.

Синтаксис

obj.watch(prop, handler)

Параметри

prop
Ім'я властивості об'єкта, за змінами якої ви бажаєте стежити.
handler
Функція, яка викликатиметься, коли значення вказаної властивості змінюється.

Значення, що повертається

undefined.

Опис

Стежить за присвоєнням значень властивості 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, щоб перевірити будь-які присвоєння значень властивостям об'єкта. Даний приклад перевіряє, що кожна людина (Person) завжди матиме дійсне ім'я (name) та вік (age) між 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);
console.log(will);   // Вілл, 29

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

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

Цей скрипт виведе наступне:

Вілл, 29
RangeError: помилкове ім'я для: Вілл, 29
RangeError: помилковий вік для: Вілл, 29

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

Не є частиною жодних специфікацій. Реалізований у JavaScript 1.2.

Сумісність з веб-переглядачами

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
watch
DeprecatedNon-standard
Chrome No support NoEdge No support NoFirefox No support 1 — 58IE No support NoOpera No support NoSafari No support NoWebView Android No support NoChrome Android No support NoFirefox Android No support 4 — 58Opera Android No support NoSafari iOS No support NoSamsung Internet Android No support Nonodejs No support No

Legend

No support  
No support
Non-standard. Expect poor cross-browser support.
Non-standard. Expect poor cross-browser support.
Deprecated. Not for use in new websites.
Deprecated. Not for use in new websites.

Примітки щодо сумісності

  • Цей Поліфіл надає метод watch для усіх переглядачів, що сумісні з ES5.
  • Використання Proxy дозволяє робити навіть більш глибокі зміни у роботі з присвоєнням властивостей.
  • Виклик watch() на об'єкті Document викидає помилку TypeError, починаючи з Firefox 23 (bug 903332). Це було виправлено у Firefox 27.

Див. також