Skip to content

Instantly share code, notes, and snippets.

@Erutan409
Forked from eligrey/object-watch.js
Last active March 14, 2018 13:43
Show Gist options
  • Save Erutan409/56d8fe1b9d768996802036ae803ff304 to your computer and use it in GitHub Desktop.
Save Erutan409/56d8fe1b9d768996802036ae803ff304 to your computer and use it in GitHub Desktop.
object.watch polyfill in ES5
/*
* object.watch polyfill
*
* 2012-04-03
*
* By Eli Grey, http://eligrey.com
* Public Domain.
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
* Modified by Michael Keyser
* 2018-03-14
*/
Object.defineProperties(Object.prototype, {
watch: {
value: function (prop, handler) {
if (handler === undefined) {
return this.__watched__.hasOwnProperty(prop);
} else if (this.__watched__.hasOwnProperty(prop)) {
throw new Error('Cannot watch property more than once');
}
this.__watched__[prop] = Object.getOwnPropertyDescriptor(this, prop);
var ref = this.__watched__[prop],
oldval = ref.get(),
newval = oldval,
getter = function () {
return ref.get();
},
setter = function (val) {
oldval = newval;
newval = val;
ref.set(newval);
handler.call(this, newval, oldval);
};
if (delete this[prop]) { // can't watch constants
Object.defineProperty(this, prop, {
get: getter,
set: setter,
enumerable: Boolean(ref.enumerable),
configurable: true
});
} else {
throw new Error('Property cannot be watched');
}
}
},
unwatch: {
value: function (prop) {
if (!this.watch(prop)) {
return false;
}
delete this[prop];
Object.defineProperty(this, prop, this.__watched__[prop]);
delete this.__watched__[prop];
return true;
}
},
__watched__: {
value: {},
writable: true
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment