Skip to content

Instantly share code, notes, and snippets.

@jelkand
Last active October 11, 2022 22:10
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jelkand/4231647570e22a5e0328d26eca7658a2 to your computer and use it in GitHub Desktop.
Save jelkand/4231647570e22a5e0328d26eca7658a2 to your computer and use it in GitHub Desktop.
Using Proxy to track changes to JS objects
// usage:
const obj = { foo: 'bar' };
const proxiedObj = attachProxy(obj);
proxiedObj.foo = 'baz';
/* output:
VM192:4 setting value of prop: foo to value: baz obj {foo: "bar"}
VM192:5 console.trace
set @ VM192:5
(anonymous) @ VM217:4
*/
const attachProxy = (target) => {
const handler = {
set(obj, prop, value) {
console.log('setting value of prop:', prop, 'to value:', value, 'obj', obj);
console.trace();
return Reflect.set(...arguments);
}
};
return new Proxy(target, handler);
}

Tracking changes to JavaScript objects using the ES6 Proxy Object

Have you ever logged out the contents of an object in 47 different places in your code, trying to see where object.foo got changed from 'bar' to 'baz'? I know I have!

The good news is, there's a better way!

How it works

The Proxy object is a way to intercept or 'trap' fundamental behavior on javascript objects, providing an entry point into that action to inspect or even redefine that behavior.

The proxy object takes two arguments. 1: the target, which is the object we want to inspect. 2: the handler which is a collection of traps. The supported traps include set, which intercepts behavior to change a property on the object, get, which intercepts access of a property, apply which will intercept function calls, and others. (The documentation linked below lists them all)

Common uses of Proxy include tracking access, validating changes, extending constructors, modifying access, and more. This gist provides a very simple method of tracking when a property on the object is changed--it uses the set trap and logs the prop to be changed, the value it's being changed to, and the object that's being changed before forwarding the change back to the object.

The docs

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

Caveats

  • If an object is cloned, you'll lose your proxy and won't have visibility going forward. This might come up often in codebases that emphasize immutability.
  • Introduced with ES6, so not as helpful on older codebases.
  • (from @snapwich) Requires being able to replace the object reference with a Proxy object, which is not always possible.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment