创建 Proxy 的结构化克隆
create structured clone of Proxy
我有一个 class return 来自构造函数的代理。当我尝试在 IndexedDB 中存储此 class 的实例,或使用 window.postMessage()
发送对象时,我收到一条错误消息,指出无法克隆该对象。 structured clone algorithm 似乎无法处理 Proxy 对象。
以下代码演示错误:
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);
}
任何人都可以提出解决此问题的方法吗?我看到了两个可能的解决方案,但我不知道如何实施它们:
不要 return 来自构造函数的 Proxy,而是以某种方式在 class 声明中维护 Proxy 功能。
更改 Proxy 实例,使其适用于结构化克隆算法。
编辑: 以下更简单的代码也演示了结构化克隆错误:
const p = new Proxy({}, {});
window.postMessage(p, '*');
您可以将原始的非代理对象保存在 class 属性 中,并在您想要将其传递给 postMessage
时使用它。您可以将构造函数更改为具有可选参数,该参数将传递给代理而不是 this
。这样您就可以通过将对象传递给构造函数来重新创建对象。
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);
}
我有一个 class return 来自构造函数的代理。当我尝试在 IndexedDB 中存储此 class 的实例,或使用 window.postMessage()
发送对象时,我收到一条错误消息,指出无法克隆该对象。 structured clone algorithm 似乎无法处理 Proxy 对象。
以下代码演示错误:
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);
}
任何人都可以提出解决此问题的方法吗?我看到了两个可能的解决方案,但我不知道如何实施它们:
不要 return 来自构造函数的 Proxy,而是以某种方式在 class 声明中维护 Proxy 功能。
更改 Proxy 实例,使其适用于结构化克隆算法。
编辑: 以下更简单的代码也演示了结构化克隆错误:
const p = new Proxy({}, {});
window.postMessage(p, '*');
您可以将原始的非代理对象保存在 class 属性 中,并在您想要将其传递给 postMessage
时使用它。您可以将构造函数更改为具有可选参数,该参数将传递给代理而不是 this
。这样您就可以通过将对象传递给构造函数来重新创建对象。
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);
}