-
-
Save Erutan409/56d8fe1b9d768996802036ae803ff304 to your computer and use it in GitHub Desktop.
object.watch polyfill in ES5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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