Home >Web Front-end >JS Tutorial >Can I Still Monitor Object Changes Across Browsers After Object.watch() Was Deprecated?
Cross-Browser Object Change Monitoring with Object.watch()
Question: Is there a way to monitor object changes consistently across multiple browsers, despite the deprecation of Object.watch()?
Answer from 'pseudoecstatic':
Yes, I developed a simple Object.watch() shim that works seamlessly across IE8, Safari, Chrome, Firefox, Opera, and other popular browsers.
Implementation:
Include the following shim in your project:
<code class="javascript">(function () { var toString = Object.prototype.toString, isNative = function (obj) { return toString.call(obj) === '[object Object]'; }, attachListener = function (target, prop, fn) { target.__watchers__ || (target.__watchers__ = {}); target.__watchers__[prop] || (target.__watchers__[prop] = []); target.__watchers__[prop].push(fn); }, detachListener = function (target, prop, fn) { if (target.__watchers__ && target.__watchers__[prop]) { var watchers = target.__watchers__[prop]; for (var i = 0; i < watchers.length; i++) { if (watchers[i] === fn) { watchers.splice(i, 1); if (watchers.length === 0) { delete target.__watchers__[prop]; } break; } } } }, getWatchers = function (target, prop) { if (target.__watchers__ && target.__watchers__[prop]) { return target.__watchers__[prop]; } return []; }, notifyWatchers = function (target, prop, oldValue, newValue) { var watchers = getWatchers(target, prop); for (var i = 0; i < watchers.length; i++) { try { var newval = watchers[i](prop, oldValue, newValue); if (isNative(newval)) { newValue = newval; } } catch (e) { setTimeout(function () { throw e; }, 0); } } return newValue; }, convert = function (prop, fn, target, rec) { var orig = target[prop]; Object.defineProperty(target, prop, { configurable: true, enumerable: true, get: function () { return orig; }, set: function (value) { if (orig !== value) { var oldval = orig; orig = notifyWatchers(target, prop, orig, value); fn(prop, oldval, orig, target); } } }); if (rec && isNative(orig)) { for (var subprop in orig) { convert(subprop, fn, orig, rec); } } }, watch = function (target, prop, fn, rec) { if (!target || typeof prop !== 'string' || typeof fn !== 'function') { throw new Error('Bad arguments'); } attachListener(target, prop, fn); fn(prop, target[prop], target[prop], target); if (rec && isNative(target[prop])) { for (var p in target[prop]) { convert(p, fn, target[prop], true); } } }, unwatch = function (target, prop, fn) { if (!target || typeof prop !== 'string') { throw new Error('Bad arguments'); } detachListener(target, prop, fn); }, constrained = function (val, defval) { if (val !== null && val !== undefined) { return val; } else { return defval; } }, watchEvery = function (obj, fn, rec) { rec = constrained(rec, false); for (var p in obj) { convert(p, fn, obj, rec); } }, stopWatchingEvery = function (obj, fn) { for (var p in obj) { unwatch(obj, p, fn); delete obj.__watchers__[p]; } }; Object.watch = watch; Object.unwatch = unwatch; Object.watchEvery = watchEvery; Object.stopWatchingEvery = stopWatchingEvery; })();</code>
Usage:
You can now use the Object.watch() shim as follows:
<code class="javascript">var options = {'status': 'no status'}, watcher = Object.watch(options, 'status', function (prop, oldValue, newValue) { // Do something with the change... }); watcher.status = 'asdf'; watcher.status = '1234';</code>
Cross-Browser Compatibility:
This shim ensures that Object.watch() functionality is consistent across all major browsers, including those that do not natively support it.
The above is the detailed content of Can I Still Monitor Object Changes Across Browsers After Object.watch() Was Deprecated?. For more information, please follow other related articles on the PHP Chinese website!