2017-05-22 4 views
2

Ich habe eine Klasse, die einen Proxy aus dem Konstruktor zurückgibt. Wenn ich versuche, Instanzen dieser Klasse in IndexedDB zu speichern oder das Objekt mit window.postMessage() zu senden, erhalte ich einen Fehler, der besagt, dass das Objekt nicht geklont werden konnte. Scheint, dass structured clone algorithm Proxy-Objekte nicht verarbeiten kann.erstellen strukturierten Klon von Proxy

Der folgende Code demonstriert den Fehler:

class MyClass { 
 
    constructor() { 
 
    return new Proxy(this, { 
 
     set(target, prop, val, receiver) { 
 
     console.log(`"${prop}" was set to "${val}"`); 
 
     return Reflect.set(target, prop, val, receiver); 
 
     } 
 
    }); 
 
    } 
 
} 
 

 
const obj = new MyClass; 
 

 
try { 
 
    window.postMessage(obj,'*'); 
 
} catch(err) { 
 
    console.error(err); 
 

 
}

Kann mir jemand eine Abhilfe für dieses Problem vorschlagen? Ich sehe zwei mögliche Lösungen, aber ich weiß nicht, wie ich sie umsetzen könnte:

  1. Sie Rückkehr keinen Proxy aus dem Konstruktor, aber die Proxy-Funktionalität innerhalb der Klassendeklaration irgendwie aufrechtzuerhalten.

  2. Ändern Sie die Proxy-Instanz, sodass sie mit dem strukturierten Klonalgorithmus funktioniert.

EDIT: Die folgende, einfacher Code zeigt auch den strukturierten Klon Fehler:

const p = new Proxy({}, {}); 
 
window.postMessage(p, '*');

Antwort

2

Sie können in einer Klasse Eigenschaft das ursprüngliche, nicht-Proxy-Objekt speichern , und verwenden Sie es, wenn Sie es an postMessage übergeben möchten. Sie können den Konstruktor so ändern, dass er einen optionalen Parameter hat, der anstelle von this an den Proxy übergeben wird. Auf diese Weise können Sie das Objekt neu erstellen, indem Sie es an den Konstruktor übergeben.

class MyClass { 
 
    constructor(original = this) { 
 
    this.original = original; 
 
    return new Proxy(original, { 
 
     set(target, prop, val, receiver) { 
 
     console.log(`"${prop}" was set to "${val}"`); 
 
     return Reflect.set(target, prop, val, receiver); 
 
     } 
 
    }); 
 
    } 
 
    export() { 
 
    return this.original; 
 
    } 
 
    static import(original) { 
 
    return new MyClass(original); 
 
    } 
 
} 
 

 
const obj = new MyClass; 
 

 
obj.test = 1; 
 
console.log(MyClass.import(obj.export()).test); 
 
MyClass.import(obj.export()).test = 2; 
 

 
try { 
 
    window.postMessage(obj.export(), '*'); 
 
} catch(err) { 
 
    console.error(err); 
 
}

+0

Dank Michał. Genau so habe ich das Problem auch gelöst. Ich würde immer noch eine der beiden anderen Lösungen bevorzugen, die ich erwähnt habe, aber dies scheint die beste Lösung zu sein. – dwhieb

Verwandte Themen