如何告诉 postMessage 结构化克隆忽略属性?
How to tell postMessage structured clone to ignore properties?
我正在做一个项目,我需要在 iframe 中创建一个对象,然后将所述对象发送给父级 window。
问题是 postMessage
失败,因为无法克隆对象 (DataCloneError
),因为它具有函数 (callback
) 属性.
更复杂的是,存在循环关系,按钮列表包含按钮,每个按钮都有对其父列表的引用。
如果这是使用 JSON.stringify
而不是结构化克隆,可以覆盖按钮上的 toJSON
并避免发送 callback
并将 list
替换为 listId
来避免循环引用的情况。是否有等同于 toJSON
的结构化克隆,允许在保持循环关系或其他解决方案的同时忽略 callback
?
这是可重现错误的情况的大致要点:
class ButtonList {
constructor() {
this.buttons = [];
}
addButton(button) {
if (!this.buttons.includes(button)) {
this.buttons.push(button);
button.setList(this);
}
return this;
}
}
class Button {
setList(list) {
if (!list) return this;
if (this.list !== list) {
this.list = list;
list.addButton(this);
}
return this;
}
setCallback(callback) {
this.callback = callback;
return this;
}
getCallback() {
return this.callback;
}
runCallback() {
if (!this.callback) return this;
this.callback();
return this;
}
}
const list = new ButtonList();
const button = new Button().setList(list).setCallback(() => console.log('Hello'));
window.postMessage(list, '*');
// DataCloneError: The object could not be cloned.
父 window 不需要知道回调,但需要知道任何其他属性。
使用 Object.assign
创建一个具有覆盖属性的新对象并通过 postMessage
发送它。
const foo = {
bar: 'bar',
list: { bla: 'bla' },
baz: function() {
console.log('baz')
}
}
const serializable = Object.assign({}, foo, {
list: 3,
baz: undefined
})
console.log(serializable)
我正在做一个项目,我需要在 iframe 中创建一个对象,然后将所述对象发送给父级 window。
问题是 postMessage
失败,因为无法克隆对象 (DataCloneError
),因为它具有函数 (callback
) 属性.
更复杂的是,存在循环关系,按钮列表包含按钮,每个按钮都有对其父列表的引用。
如果这是使用 JSON.stringify
而不是结构化克隆,可以覆盖按钮上的 toJSON
并避免发送 callback
并将 list
替换为 listId
来避免循环引用的情况。是否有等同于 toJSON
的结构化克隆,允许在保持循环关系或其他解决方案的同时忽略 callback
?
这是可重现错误的情况的大致要点:
class ButtonList {
constructor() {
this.buttons = [];
}
addButton(button) {
if (!this.buttons.includes(button)) {
this.buttons.push(button);
button.setList(this);
}
return this;
}
}
class Button {
setList(list) {
if (!list) return this;
if (this.list !== list) {
this.list = list;
list.addButton(this);
}
return this;
}
setCallback(callback) {
this.callback = callback;
return this;
}
getCallback() {
return this.callback;
}
runCallback() {
if (!this.callback) return this;
this.callback();
return this;
}
}
const list = new ButtonList();
const button = new Button().setList(list).setCallback(() => console.log('Hello'));
window.postMessage(list, '*');
// DataCloneError: The object could not be cloned.
父 window 不需要知道回调,但需要知道任何其他属性。
使用 Object.assign
创建一个具有覆盖属性的新对象并通过 postMessage
发送它。
const foo = {
bar: 'bar',
list: { bla: 'bla' },
baz: function() {
console.log('baz')
}
}
const serializable = Object.assign({}, foo, {
list: 3,
baz: undefined
})
console.log(serializable)