How to test if an object is a Proxy?
In my current project I also needed a way of defining if something was already a Proxy, mainly because I didn't want to start a proxy on a proxy. For this I simply added a getter to my handler, which would return true if the requested variable was "__Proxy":
function _observe(obj) {
if (obj.__isProxy === undefined) {
var ret = new Proxy(obj || {}, {
set: (target, key, value) => {
/// act on the change
return true;
},
get: (target, key) => {
if (key !== "__isProxy") {
return target[key];
}
return true;
}
});
return ret;
}
return obj;
}
Might not be the best solution, but I think it's an elegant solution, which also doesn't pop up when serializing.
In Node.js 10 you can use util.types.isProxy
.
For example:
const target = {};
const proxy = new Proxy(target, {});
util.types.isProxy(target); // Returns false
util.types.isProxy(proxy); // Returns true
Create a new symbol:
let isProxy = Symbol("isProxy")
Inside the get
method of your proxy handler you can check if the key
is your symbol and then return true
:
get(target, key)
{
if (key === isProxy)
return true;
// normal get handler code here
}
You can then check if an object is one of your proxies by using the following code:
if (myObject[isProxy]) ...
From http://www.2ality.com/2014/12/es6-proxies.html:
It is impossible to determine whether an object is a proxy or not (transparent virtualization).
Adding 'support' for instanceof Proxy
:
I don't recommend it, but If you want to add support for instanceof
, you could do the following before instantiating any Proxies:
(() => {
var proxyInstances = new WeakSet()
// Optionally save the original in global scope:
originalProxy = Proxy
Proxy = new Proxy(Proxy, {
construct(target, args) {
var newProxy = new originalProxy(...args)
proxyInstances.add(newProxy)
return newProxy
},
get(obj, prop) {
if (prop == Symbol.hasInstance) {
return (instance) => {
return proxyInstances.has(instance)
}
}
return Reflect.get(...arguments)
}
})
})()
// Demo:
var a = new Proxy({}, {})
console.log(a instanceof Proxy) // true
delete a
var a = new originalProxy({}, {})
console.log(a instanceof Proxy) // false
delete a