【问题标题】:How to tell postMessage structured clone to ignore properties?如何告诉 postMessage 结构化克隆忽略属性?
【发布时间】:2019-01-31 16:19:55
【问题描述】:

我正在做一个项目,我需要在 iframe 中创建一个对象,然后将所述对象发送到父窗口。

问题是 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.

父窗口不需要知道回调,但需要知道任何其他属性。

【问题讨论】:

    标签: javascript postmessage structured-clone


    【解决方案1】:

    使用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)

    【讨论】:

    • 谢谢,这行得通。只是想知道,是否存在性能问题,因为这需要克隆列表,然后遍历列表中的所有按钮并使用未定义的回调克隆它们?
    • @shaneod 性能问题是相对的;当然,Object.assign() 会在这里创建一个新对象,但您打算为数百万个大型对象执行此操作吗?此外,不相关但可能更重要的是,您应该小心 Object.assign 不会进行深度克隆。
    • 这个数字足够小。这种方法听起来不错。谢谢:)
    猜你喜欢
    • 2017-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    • 2011-11-17
    • 1970-01-01
    • 2017-11-12
    • 1970-01-01
    相关资源
    最近更新 更多