Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there Proxy-object polyfill available google chrome?

Is this even possible? How about other browsers? Any estimates when es6 will be "ready" and rolled out?

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

btw. https://github.com/tvcutsem/harmony-reflect Proxy does not work with current chrome (36.0.n)

like image 332
pasuna Avatar asked Jul 23 '14 09:07

pasuna


People also ask

Can I use proxy object?

The Proxy object allows you to create an object that can be used in place of the original object, but which may redefine fundamental Object operations like getting, setting, and defining properties. Proxy objects are commonly used to log property accesses, validate, format, or sanitize inputs, and so on.

What is a proxy object JavaScript?

In JavaScript, proxies (proxy object) are used to wrap an object and redefine various operations into the object such as reading, insertion, validation, etc. Proxy allows you to add custom behavior to an object or a function.

What does a proxy do to the target object Ecmascript?

A proxy allows you to perform meta-programming operations such as intercepting a call to inspect or change an object's property. The original object the proxy will virtualize.


1 Answers

You could use Object.defineProperty and Object.observe to to simulate a Proxy. I started to wonder how much functionality a polyfill could support, so I wrote an implementation (you can see it at gist.github.com/mailmindlin/640e9d707ae3bd666d70). I was able to emulate all of the features of Proxy that didn't rely on operator overloading, whic isn't possible in JavaScript as of now.

However, you can get the get, set, and a few others working. You can use getters and setters to mirror the target object's properties:

for (var property in target)
    Object.defineProperty(proxy, property, {
        get: function() {
            if ('get' in handler)
                return handler.get(target, property, proxy);
            else
                return target[property];
       },
       set: function(value) {
           if ('set' in handler)
               handler.set(target, property, value, proxy);
           else
               target[property] = value;
      }});

The only problem with that is that the getters and setters only apply to properties that were defined in for the target when the proxy was initialized, and the delete operator won't work (If you delete a property on the target object, the proxy will still enumerate it as a property; if you delete a property on the proxy, nothing will happen to the object).

To fix that, you can use Object.observe which will be called on any change to either object. A quick check on caniuse.com shows that Object.observe is available on Chrome and Opera. If you really need support for Proxy on another browser, you can poll the target and proxy objects, to check if any properties have been created or destroyed:

var oldKeys = Object.keys(proxy);
setInterval(function() {
    var keys = Object.keys(proxy);
    for(var i in keys)
        if(!oldKeys.includes(keys[i]))
            //Trigger code for a new property added

    for(var i in oldKeys)
        if(!keys.includes(oldKeys[i]))
            //trigger code for a deleted property

    oldKeys = keys;

    //repeat for target object
}, 100);

If you desperately need more features of the proxy, you can try overriding methods such as Object.defineProperty and Object.getOwnPropertyDescriptor, but that might create compatibility issues with other scripts, depending on how you do it.

In short, you can do most of what you'll probably need to use Proxy for with a polyfill. As far as Google adding it to their browser, I have no idea. It apparently used to be part of the V8 engine, but it was removed because of security problems (that nobody elaborates on), as far as I could tell based on this thread.

like image 98
mailmindlin Avatar answered Oct 13 '22 00:10

mailmindlin