Skip to content

Instantly share code, notes, and snippets.

@samuelluis
Forked from eligrey/object-watch.js
Last active August 26, 2016 23:45
Show Gist options
  • Save samuelluis/be98fb159c536cad8afdcfdc0e2869d0 to your computer and use it in GitHub Desktop.
Save samuelluis/be98fb159c536cad8afdcfdc0e2869d0 to your computer and use it in GitHub Desktop.
object.watch polyfill in ES5
if (!Object.prototype.typeof) {
Object.defineProperty(Object.prototype, "typeof", {
enumerable: false
, configurable: true
, writable: false
, value: function (Type) {
toString = Object.prototype.toString;
return toString.call(this) == toString.call(new Type());
}
});
}
if (!Object.prototype.deep) {
Object.defineProperty(Object.prototype, "deep", {
enumerable: false
, configurable: true
, writable: false
, value: function (path) {
obj = this;
if(path.typeof(String)) path = path.split(".");
prop = path.splice(0,1).toString();
if(prop && prop != ""){
if(!obj[parseInt(prop) || prop]) return undefined;
return obj[parseInt(prop) || prop].deep(path);
}
else return obj.valueOf();
}
});
}
if (!Object.prototype.watch) {
Object.defineProperty(Object.prototype, "watch", {
enumerable: false
, configurable: true
, writable: false
, value: function (prop, handler) {
console.log("watch,", "from", this, "- with", arguments);
var
main = this
, oldval = this.deep(prop)
, newval = oldval
, getter = function () {
return newval;
}
, setter = function (val) {
if(val.typeof(Array) || val.typeof(Object)) val.observe(null, handler, main, prop);
console.log("val", val, "- ", JSON.stringify(val));
oldval = newval;
handler.call(this, prop, oldval, val);
return newval = val;
}
;
obj = main;
props = prop.split(".");
key = prop;
if((q = props.length) > 1){
key = props.splice(q-1, q)[0];
//console.log("props", props);
obj = obj.deep(props.join("."));
}
//console.log("object", obj, "- key", key);
if (key!= "" && delete obj[key]) { // can't watch constants
Object.defineProperty(obj, key, {
get: getter
, set: setter
, enumerable: true
, configurable: true
});
}
}
});
}
// object.unwatch
if (!Object.prototype.unwatch) {
Object.defineProperty(Object.prototype, "unwatch", {
enumerable: false
, configurable: true
, writable: false
, value: function (prop) {
var val = this[prop];
delete this[prop]; // remove accessors
this[prop] = val;
}
});
}
// object.observe
if (!Object.prototype.observe) {
Object.defineProperty(Object.prototype, "observe", {
enumerable: false
, configurable: true
, writable: false
, value: function (prop, handler, main, attr) {
console.log("observe,", "from", this, "- with", arguments);
var main = main || this
, attr = attr || prop
, obj = this.deep(prop || "");
if(obj.typeof(Array) || obj.typeof(Object)){
var prefix = (attr) ? attr + "." : "";
for(i in obj){
obj.observe(i.toString(), handler, main, prefix + i.toString());
}
}
main.watch(attr, handler);
}
});
}
handler = function(prop, prev, curr){
console.log(prop, "| from:", JSON.stringify(prev), "- to:", JSON.stringify(curr));
};
obj = {a: 1, b: {a: 2}, c: [3,4], d: [{a: 5}, {a: 6, b: {a: 7}}]}
obj.observe("", handler);
obj.a = 2;
obj.a = 1;
obj.b.a = 3;
obj.b = {a: "3"};
obj.b.a = 2;
obj.c[1] = 5;
obj.c[0] = 4;
obj.c = ["3", "4"];
obj.c[0] = 3;
obj.c[1] = 4;
obj.d[0].a = 6;
obj.d[0] = {a: "6"};
console.log("obj:", JSON.stringify(obj));
obj.d[0].a = 5;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment