So greifen Sie auf das Ziel zu (das ist myArray) von myProxy Hier?
function createProxy() {
const myArray = [Math.random(), Math.random()];
return new Proxy(myArray, {});
}
const myProxy = createProxy();
Ich hätte gerne eine getProxyTarget Funktion, die das ursprüngliche Objekt zurückgeben würde, ohne einen anderen Teil des Codes zu ändern:
let original;
function createProxy() {
const myArray = [Math.random(), Math.random()];
original = myArray;
return new Proxy(myArray, {});
}
const myProxy = createProxy();
function getProxyTarget(proxy){ /* ... your code */ }
console.log(getProxyTarget(myProxy) === original) // should be true
Das kannst du nicht. Deshalb ist es ein Proxy. Was versuchst du zu tun, warum brauchst du das?
– Bergi
29. Juni 2018 um 7:54
@Bergi Denn wenn ich ein Objekt mit Zirkelverweisen habe und diese Zirkelverweise sich in Proxys befinden, gibt es keine Möglichkeit dazu sicher stringifizieren mein Objekt. Ich erhalte die Fehlermeldung „Stapelgröße überschritten“. 🙁
– Adam
29. Juni 2018 um 7:59
Können Sie bitte ein Beispiel dafür geben? Zirkelverweise (ich glaube, Sie meinen diese, nicht Abhängigkeiten) sollte problemlos mit Proxys funktionieren, z myProxy === myProxy hält immer noch. Nichts muss das Ziel erreichen.
– Bergi
29. Juni 2018 um 8:02 Uhr
Caleb Waldner
Wenn Sie Vue 3 verwenden und mit Proxies arbeiten, bietet Vue einige Methoden, die Ihnen dabei helfen:
import { isProxy, toRaw } from 'vue';
Mithilfe dieser können Sie überprüfen, ob ein Objekt ein Proxy ist isProxyZum Beispiel:
isProxy(reactiveObjectOrArray) ? 'yup' : 'nope'
Und Sie können die Rohdaten mit extrahieren toRaw:
Seltsamerweise, isProxy Und toRaw Scheint nur mit reaktiven Objekten zu funktionieren, die mit erstellt wurden reactive Funktion, nicht die häufigere ref. Wie um alles in der Welt soll man das Originalobjekt für einen bekommen? ref reaktiver Wert?
– Jez
7. November 2022 um 12:04
Interessanterweise musste ich nie einen konvertieren ref Das ist mir also nie aufgefallen, aber wenn ich es selbst teste, sehe ich, dass Sie Recht haben; A ref funktioniert mit diesen beiden Funktionen nicht. Wenn jemand wirklich einen konvertieren müsste refsie könnten es gebrauchen toReactive von VueUse, wodurch ich meine konvertieren konnte ref in ein reaktives Objekt. Das hat bei mir funktioniert, aber ich glaube, es funktioniert nur bei Objekten; Zeichenfolgen, boolesche Werte und dergleichen funktionieren mit dieser Methode möglicherweise nicht.
– Caleb Waldner
8. November 2022 um 4:27
Haben Sie das mit einer Vorlagenreferenz versucht, bei der ich den zugrunde liegenden Typ herausfinden wollte? const playfieldRef = ref(null); const pref = playfieldRef; const prefValue = playfieldRef.value; const prefReactive = toReactive(pref); const prIsProxy = isProxy(prefReactive); /* false */ const prRaw = toRaw(prefReactive); /* Proxy {} */
Ja, das habe ich auch ausprobiert, es ist seltsam, es gibt mir einen etwas anderen Proxy zurück, der mir bei der Auswertung Folgendes in der Konsole anzeigt: Proxy {__v_skip: true, getStage: ƒ, getNode: ƒ}. Wenn ich das Objekt öffne, hat es [[Handler]]: Object, [[Target]]: ProxyUnd [[IsRevoked]]: false drauf, aber nicht getStage oder getNode Funktionen. Scheint immer noch kein zugrunde liegendes Objekt zu sein; es sei denn, ich bin dumm und die Originalbibliothek stellt tatsächlich selbst einen Proxy bereit. Hmm.
– Jez
10. November 2022 um 11:01 Uhr
Rashad Saleh
Mit können Sie eine Kopie der vom Proxy zurückgegebenen Daten erstellen Object.assign():
Mein Beispielszenario erforderte die Verarbeitung eines Proxys, der als Promise-Ablehnung von einem Web-API-Aufruf zurückgegeben wurde. Die vollständige Zeile sah so aus: var m = Object.assign({}, rejected)[0].message; . Danke Rashad!
– Shanerk
23. Januar 2019 um 19:54
Dies beantwortet die Frage nicht. Die Daten von target_copy wird weiterhin von Proxy-Accessoren beeinflusst; und Sie haben keinen Verweis auf das Originalobjekt.
– Leonardo Raele
4. Oktober 2021 um 6:12 Uhr
Dies funktioniert nicht, wenn das Ziel ein Array ist und Sie das Array zurückerhalten möchten.
– Chetan
17. November 2021 um 7:30 Uhr
Ich finde, dass ich (bei Verwendung von Vue.js, wo manchmal Proxy-Objekte beteiligt sind, z. B. beim Beobachten einer Komponenten-Requisite) das Ziel sowohl erhalten kann, wenn es ein Objekt ist, als auch wenn es ein Array ist JSON.stringify:
let myTarget = JSON.parse(JSON.stringify(myProxy))
Dieser Ansatz funktioniert auch mit Array-Zielen Object.assign({}, myProxy) Funktioniert nur, wenn das Ziel ein Objekt ist.
Aber ich bin ein Neuling in Sachen JavaScript-Proxys und meine Kenntnisse sind begrenzt. Möglicherweise verstehe ich die Einschränkungen und Vorbehalte dieses Ansatzes nicht. Trotzdem hilft es vielleicht jemandem!
Danke. Das ist es, was ich brauchte. Ich brauchte das Ziel eines von Vue erstellten Proxys, damit ich es als Teil einer Abrufanforderung übergeben konnte.
– Mike Ryan
23. Januar 2021 um 22:24
Gute Antwort für ältere Versionen, aber ziehen Sie toRaw in Betracht, wenn Sie Vue3 verwenden …
– JL Peyret
1. November 2022 um 7:25 Uhr
Davidiusdadi
Wie die anderen Antworten bereits sagten a Proxy erhält Falle kann eine elegante Lösung sein.
Dieses Codebeispiel sollte ziemlich robust sein, da es:
vermeidet Konflikte bei Eigenschaftsnamen durch die Verwendung von a Symbol
deckt alle Get-Szenarien mit ab Reflect.get anstatt target[property]
WARNUNG: Seien Sie vorsichtig bei der Prototypenvererbung – für den Fall, dass Ihr Proxy letztendlich als Prototyp verwendet wird not_itself_a_proxy[IDENTITY] Der Anruf wird nicht zurückgegeben not_itself_a_proxy sondern die „Identität“ des Prototyps!
Es gibt eine clevere Möglichkeit, dies zu tun: Sie können eine hinzufügen erhalten trap an den Proxy senden und ihn zurückgeben lassen Ziel bedingt. So..
let resolveMode = false; // Switch that controls if getter returns target or prop.
function resolve(obj) {
resolveMode = true; // Turn on our switch
let target = obj.anything; // This gets the target not the prop!
resolveMode = false; // Turn off the switch for the getter to behave normally
return target; // Return what we got!
}
function createProxy() {
const myArray = [Math.random(), Math.random()];
return new Proxy(myArray, {
get: function(target, prop) {
if (resolveMode) return target; // This is where the magic happens!
else return target[prop]; // This is normal behavior..
}
});
}
const myProxy = createProxy();
let target = resolve(myProxy);
Denken Sie daran, dass die Leistung des Objekts umso langsamer wird, je mehr Codezeilen Sie zu Traps hinzufügen. Hoffe das hilft.
Dies ist nur dann möglich, wenn Sie Zugriff auf den Quellcode des Proxys haben.
– Leonardo Raele
4. Okt. 2021 um 6:13
Timkay
Die anderen Antworten gaben einige gute Lösungen. Hier ist die Antwort von @Yuci für Klassen zusammengefasst. In diesem Fall ist es so einfach wie das Definieren einer Instanzvariablen mit einem speziellen Namen. Die Proxy-Get-Funktion gibt es zurück, ebenso wie das zugrunde liegende Ziel.
class Foo {
constructor() {
this.__target__ = this;
return new Proxy(this, {
get: function (target, name) {
if (name in target) return target[name];
// your code here
}
});
}
}
let foo = new Foo();
let target = foo.__target__;
console.log('proxied Foo', foo);
console.log('recovered target', target, target.__target__.__target__);
Dies ist nur dann möglich, wenn Sie Zugriff auf den Quellcode des Proxys haben.
– Leonardo Raele
4. Okt. 2021 um 6:13
Wie wäre es mit dem Hinzufügen der folgenden Get-Trap:
Das kannst du nicht. Deshalb ist es ein Proxy. Was versuchst du zu tun, warum brauchst du das?
– Bergi
29. Juni 2018 um 7:54
@Bergi Denn wenn ich ein Objekt mit Zirkelverweisen habe und diese Zirkelverweise sich in Proxys befinden, gibt es keine Möglichkeit dazu sicher stringifizieren mein Objekt. Ich erhalte die Fehlermeldung „Stapelgröße überschritten“. 🙁
– Adam
29. Juni 2018 um 7:59
Können Sie bitte ein Beispiel dafür geben? Zirkelverweise (ich glaube, Sie meinen diese, nicht Abhängigkeiten) sollte problemlos mit Proxys funktionieren, z
myProxy === myProxy
hält immer noch. Nichts muss das Ziel erreichen.– Bergi
29. Juni 2018 um 8:02 Uhr