2016-04-02 21 views
18

Chciałbym przetestować, czy obiekt JavaScript jest Proxy. Trywialne podejścieJak sprawdzić, czy obiekt jest proxy?

if (obj instanceof Proxy) ... 

tu nie pracuje, ani nie przechodzą przez łańcuch prototypowy dla Proxy.prototype, ponieważ wszystkie istotne operacje są skutecznie wspierane przez bazowego cel.

Czy można sprawdzić, czy dowolny obiekt jest proxy?

+0

Może proxy Proxy? Mam na myśli proxy funkcję Proxy przed jakimkolwiek skryptem z udziałem Proxy .. – user943702

+0

Czy to nie jest celem serwerów proxy, że nie można ich odróżnić od "normalnego" obiektu? Dlaczego chcesz to przetestować? – Bergi

+1

@Bergi cóż, z pewnością nie jest to główny cel serwerów proxy. Co do reszty, jestem nieco zaskoczony, że nie możesz wymyślić przypadek użycia dla tego testu. –

Odpowiedz

8

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

To jest niemożliwe, aby określić, czy obiekt jest proxy lub nie (przezroczysty wirtualizacji).

+9

Nie będę łączył artykułu, który zaczyna się od notatki "* ten wpis na blogu jest nieaktualny *" :-) Jednak http://exploringjs.com/es6/ch_proxies.html stwierdza dokładnie to samo – Bergi

+0

@ Komentarz Bergiego powinien być zaakceptowaną odpowiedzią. – BrassApparatus

+1

@BrassApparatus W rzeczywistości okazuje się, że zarówno jego komentarz, jak i moja odpowiedź są błędne, jak [tutaj] [http://exploringjs.com/es6/ch_proxies.html#_pitfall-not] -all-objects-can-be-wrapped-transparent-by-by-proxy). –

0

Istnieją dwa sposoby na wykonanie proxy obiektu. Jedna to new Proxy, druga to Proxy.revocable. Możemy je szpiegować, aby obiekt pośredni został zapisany na tajnej liście. Następnie ustalamy, że obiekt jest obiektem proxy, sprawdzając, czy istnieje na tajnej liście.

Do funkcji szpiegowskich możemy pisać opakowania lub korzystać z wbudowanego serwera proxy. To drugie oznacza, że ​​używasz proxy do proxy new Proxy, a także Proxy.recovable, tutaj jest fiddle, aby zaprezentować pomysł.

Służyć itp nodejs-v5.8.0 Proxy, możemy zastosować ten sam pomysł za pomocą Proxy.createFunction do pełnomocnika Proxy.create i Proxy.createFunction.

+0

To podejście nie działa w przypadku serwerów proxy utworzonych w innych domenach (takich jak elementy iframe lub moduły 'vm' węzła), ponieważ nie można szpiegować globów (np.' Proxy') w innych dziedzinach. – LJHarb

9

W moim bieżącym projekcie potrzebowałem również sposobu na określenie, czy coś było już proxy, głównie dlatego, że nie chciałem uruchamiać proxy na serwerze proxy. W tym celu po prostu dodał getter do mojego przewodnika, który zwróciłby true jeśli zmienna wymagane było „__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; 
 
}

nie może być najlepszym rozwiązaniem, ale myślę, że to elegancki rozwiązanie, które również nie pojawia się podczas serializacji.

+0

Dzięki! Robię coś w rodzaju głębokiego proxy, a także dostałem się do tego problemu. –

+1

Świetnie, używam tego podejścia, ale z niewielkim akcentem: const IS_PROXY = Symbol ("jest-proxy"); ... jeśli (! Obj [IS_PROXY]) –

1

Wydaje się, że nie jest standardowy sposób, ale dla Firefoksa uprzywilejowanym kodzie można użyć

Components.utils.isProxy(object); 

na przykład:

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

Najlepszym sposobem znalazłem się tworząc słaby zestaw p? obiekty proxy. Możesz zrobić to rekurencyjnie, kiedy budujesz i sprawdzasz swoje obiekty z proxy.

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

Albo

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