2016-04-02 14 views
18

Ich möchte testen, ob ein JavaScript-Objekt ein 10 ist. Der triviale AnsatzWie testen, ob ein Objekt ein Proxy ist?

if (obj instanceof Proxy) ... 

nicht funktioniert hier noch die Prototypkette nicht durchquert für Proxy.prototype, da alle relevanten Operationen effektiv durch das zugrunde liegende Ziel gesichert werden.

Ist es möglich, zu testen, ob ein beliebiges Objekt ein Proxy ist?

+0

Vielleicht Proxy die Proxy? Ich meine, Proxy die Proxy-Funktion vor jedem Skript mit Proxy .. – user943702

+0

Ist nicht der eigentliche Zweck der Proxies, die Sie nicht von einem "normalen" Objekt unterscheiden können? Warum würdest du das testen wollen? – Bergi

+1

@Bergi, das ist natürlich nicht der Hauptzweck von Proxies. Für den Rest bin ich ein wenig überrascht, dass Sie keinen Anwendungsfall für diesen Test herausfinden können. –

Antwort

8

Von http://www.2ality.com/2014/12/es6-proxies.html:

Es ist unmöglich, zu bestimmen, ob ein Objekt ein Proxy ist oder nicht (transparente Virtualisierung).

+9

Ich würde keinen Artikel verknüpfen, der mit einer Notiz beginnt "* dieser Blogpost ist veraltet *" :-) Allerdings http://exploringjs.com/es6/ch_proxies.html gibt genau das gleiche – Bergi

+0

@ Bergis Kommentar sollte die akzeptierte Antwort sein. – BrassApparatus

+1

@BrassApparatus Tatsächlich stellt sich heraus, dass sowohl sein Kommentar als auch meine Antwort falsch sind, wie ausführlich [hier] (http://exploringjs.com/es6/ch_proxies.html#_pitfall-not -all-objects-can-wrapped-transparent-by-proxies). –

0

Es gibt zwei Möglichkeiten, ein Objekt als Proxy zu verwenden. Einer ist new Proxy, ein anderer ist Proxy.revocable. Wir können sie ausspionieren, damit das proxied Objekt in eine geheime Liste aufgenommen wird. Dann bestimmen wir, dass ein Objekt ein Proxy-Objekt ist, indem wir prüfen, ob es in der geheimen Liste existiert.

Zum Ausspionieren von Funktionen können wir Wrapper schreiben oder den integrierten Proxy verwenden. Letzteres bedeutet, dass Proxy verwenden, um new Proxy sowie Proxy.recovable Proxy, hier ist ein fiddle, um die Idee zu demontieren.

die wie NodeJS-v5.8.0 Proxy dienen, können wir durch die Verwendung Proxy.createFunction Proxy Proxy.create und Proxy.createFunction die gleiche Idee gelten.

+0

Dieser Ansatz funktioniert nicht für Proxies, die in anderen Realms erstellt wurden (wie Iframes oder Knoten 'vm' Module), weil Sie nicht Globals (wie' Proxy') in anderen Realms ausspionieren können. – LJHarb

9

In meinem aktuellen Projekt brauchte ich auch eine Möglichkeit zu definieren, ob etwas bereits ein Proxy war, hauptsächlich weil ich keinen Proxy auf einem Proxy starten wollte. Dazu habe ich einfach einen Getter zu meinem Handler, die true zurückgeben würde, wenn die angeforderte Variable „__Proxy“ war:

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; 
 
}

vielleicht nicht die beste Lösung sein, aber ich denke, es ist ein elegantes Lösung, die beim Serialisieren ebenfalls nicht erscheint.

+0

Danke! Ich mache eine Art Deep Proxy, und ich habe mich auch mit diesem Problem beschäftigt. –

+1

Großartig, ich benutze diesen Ansatz aber mit einer kleinen Wendung: const IS_PROXY = Symbol ("is-proxy"); ... wenn (! Obj [IS_PROXY]) –

1

Es scheint, dass es keine Standardmethode ist, sondern auch für Firefox privilegierten Code können Sie

Components.utils.isProxy(object); 

Zum Beispiel verwenden:

Components.utils.isProxy([]); // false 
Components.utils.isProxy(new Proxy([], {})); // true 
1

Die beste Methode, die ich gefunden habe, ist ein schwachen Satz der Schaffung Proxy-Objekte. Sie können das rekursiv tun, wenn Sie Ihre proxied-Objekte erstellen und überprüfen.

var myProxySet = new WeakSet(); 
    var myObj = new Proxy({},myValidator); 
    myProxySet.add(myObj); 

    if(myProxySet.has(myObj)) { 
     // Working with a proxy object. 
    } 
0
class MyProxy{ 
    constructor(target,desc,self=this){ 
      var 
      old_get=('get' in desc)?desc.get:function(target,prop){return target[prop];}, 
      old_has=('has' in desc)?desc.has:function(target,prop){ return (prop in target);}; 
     desc.get=function(target,prop){ 


      if(prop=='getOwnPrototypeOf'){ 
       return function() { 
        return Object.getPrototypeOf(self); 
        /* //if "getOwnPrototypeOf" is defined in "target", then do not override it. 
         if('getOwnPrototypeOf' in target){ //if "target" is MyProxy object. 
          return target.getOwnPrototypeOf(); 
         } else{ 
          return Object.getPrototypeOf(self); 
         } 
        */ 
       } 
      } else if(prop=='getOwnProxyObjectOf') { 
       return function(){ 
        return self; 
       } 
      } 
      return old_get(target,prop); 
     } 
     desc.has=function (target,prop){ 
      if(prop=='getOwnPrototypeOf'|| prop=='getOwnProxyObjectOf'){ 
       return true; 
      } 
      return old_has(target,prop); 
     } 
     return new Proxy(target,desc); 
    } 
} 

// Exemple 
class AsdProxy{ 
    constructor(target,desc,self=this){ 
     self=this; 
     return new MyProxy(target,desc,self); 
    } 

} 
class AsdProxy2{ 
    constructor(target,desc,self=this){ 
     return new MyProxy(target,desc,self); 
    } 

} 
class AsdProxy3 { 
    constructor(target,desc,self=this){ 
     return new AsdProxy2(target,desc,self); 
    } 

} 

ss=new MyProxy({},{}); 
console.log('getOwnPrototypeOf' in ss && MyProxy.prototype===ss.getOwnPrototypeOf());//true 
console.log(ss.getOwnProxyObjectOf() instanceof MyProxy); //true 

asd=new AsdProxy({},{}); 
asd2=new AsdProxy2({},{}); 
asd3 = new AsdProxy3({},{}); 
console.log(asd2.getOwnProxyObjectOf() instanceof MyProxy);// false 
console.log(asd2.getOwnProxyObjectOf() instanceof AsdProxy);//false 
console.log(asd2.getOwnProxyObjectOf() instanceof AsdProxy2); //true 
console.log(asd3.getOwnProxyObjectOf() instanceof AsdProxy2);// false 
console.log(asd3.getOwnProxyObjectOf() instanceof AsdProxy3); // true 
-1

Oder

class MyProxy{ 
    constructor(target,desc,self=this){ 

     var getMyProxyObject=Symbol.for('getMyProxyObject'), old_get=('get' in desc)?desc.get:function(target,prop){return target[prop];} 
     desc.get=function(target,prop){ 
      if(prop===getMyProxyObject){ 
       return self; 
      } 
      return old_get(target,prop); 
     } 
     return new Proxy(target,desc); 
    } 

} 


class NewProxy extends MyProxy { 
    constructor(target,desc){ 
     return super(target,desc); 
    } 
} 
var getMyProxyObject=Symbol.for('getMyProxyObject'), 
    asd=new MyProxy({},{}), 
    bsd=new NewProxy({},{}); 
console.log(asd[getMyProxyObject] instanceof MyProxy); // true 
console.log(bsd[getMyProxyObject] instanceof MyProxy); // true 
console.log(bsd[getMyProxyObject] instanceof NewProxy); // true 
console.log(NewProxy.prototype.isPrototypeOf(bsd[getMyProxyObject])); //true 
console.log(MyProxy.prototype.isPrototypeOf(bsd[getMyProxyObject])); //true 
Verwandte Themen