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