Created
November 19, 2015 17:08
-
-
Save miikka/d0508fb91abc0111b917 to your computer and use it in GitHub Desktop.
Observe property reads in JavaScript
This file contains hidden or 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
/* Recursively observe property reads of an object. | |
* | |
* Takes the target and an object for returning results. Returns the proxied | |
* target. Results are assigned to result.reads. | |
* | |
* Example: | |
* | |
* var target = {a: 1}; | |
* var result = {}; | |
* target = observeReads(target, result); | |
* console.log(result.reads['root.a']) // => undefined | |
* console.log(target.a); // => 1 | |
* console.log(result.reads['root.a']) // => true | |
* | |
* Requires Proxy, which is part of ES6 but so far only implemented by Firefox | |
* and Edge. | |
*/ | |
function observeReads(target, result) { | |
result.reads = {}; | |
function handler(prefix) { | |
var cache = {}; | |
return { | |
get: function(target, property) { | |
var key = prefix + '.' + property; | |
var value = target[property]; | |
result.reads[key] = true; | |
if (value !== null && typeof value === 'object') { | |
// We cache the proxy objects to ensure that foo.a === foo.a. If we | |
// would always return a new Proxy(...), that wouldn't be the case. | |
if (!(property in cache)) { | |
cache[property] = new Proxy(value, handler(key)); | |
} | |
return cache[property]; | |
} else { | |
return value; | |
} | |
}, | |
set: function(target, property, value) { | |
target[property] = value; | |
delete cache[property]; | |
return true; | |
} | |
} | |
} | |
return new Proxy(target, handler('root')); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment