Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript postMessage()之后还原原型方法_Javascript_Prototype_Web Worker - Fatal编程技术网

Javascript postMessage()之后还原原型方法

Javascript postMessage()之后还原原型方法,javascript,prototype,web-worker,Javascript,Prototype,Web Worker,我有以下JavaScript对象: function Node() { this.id = 0; this.parent = null; this.children = []; } Node.prototype.toString = function() { return "ID: " + this.id; }; var node = new Node(); node.id = 1; node.parent = new Node(); paren

我有以下JavaScript对象:

function Node() {
    this.id       = 0;
    this.parent   = null;
    this.children = [];
}
Node.prototype.toString = function() {
    return "ID: " + this.id;
};
var node = new Node();
node.id = 1;
node.parent = new Node();
parent.children.push(node);
node.toString();         // returns "ID: 1"
这是一个如何使用它的示例:

function Node() {
    this.id       = 0;
    this.parent   = null;
    this.children = [];
}
Node.prototype.toString = function() {
    return "ID: " + this.id;
};
var node = new Node();
node.id = 1;
node.parent = new Node();
parent.children.push(node);
node.toString();         // returns "ID: 1"
现在我有以下问题:

function Node() {
    this.id       = 0;
    this.parent   = null;
    this.children = [];
}
Node.prototype.toString = function() {
    return "ID: " + this.id;
};
var node = new Node();
node.id = 1;
node.parent = new Node();
parent.children.push(node);
node.toString();         // returns "ID: 1"
上面的示例代码是在web worker中执行的,因此节点是在那里创建的。之后,我使用将节点发送到主线程

JavaScript自动创建对象的深度副本。但是——当然——这样做时,它会创建一个普通的JavaScript对象,而不是从
节点
继承其属性的对象。因此,无法在主线程内调用
toString()
函数

恢复节点的最简单和最有效的方法是什么,这样我的原型方法就可以再次使用了?这应该在我从web worker收到对象后在主线程中完成

理想情况下,应该在不创建数据的另一个副本的情况下完成,因为它可能包含许多节点,并且具有周期


我的解决方法是放弃原型方法,而是将节点作为参数传递给自由函数。但这不是一件好事。

之后定义proto并将其添加到接收的节点,如:

let proto = node => { return {toString: () => 'ID: ' + node.id}}
let node = new Node();
node = Object.assign(node, proto(node));

为什么不在对象中添加原型FN作为普通FN,如下面所示;在节点中?然后正确地命名函数,如下所示;通过
this.toString=…
将函数直接添加到对象不起作用,因为
postMessage()
将无法复制/序列化它。而
toString()
就是一个例子。实际实现更复杂。这是事实,它不会序列化函数,您只需在之后创建does FN并将其添加到接收的节点。是的,这是一个可能的选项。缺点是,每个原型方法的所有传输节点都将获得一个附加属性。如果有很多这样的节点,也有一些这样的方法,这种方法会创建很多成员(可能会对内存造成很大的影响)。但是如果你不能修改现有的原型链,我想这是唯一的选择。我觉得自己很愚蠢。覆盖课程的原型链是有效的(
receivedNode.\uuuu proto\uuuuuu.toString=…
),但结果或多或少与您的建议完全相同。如果你把它作为一个答案发布,我会接受它,你会得到你的声誉。这有帮助吗@majaI仍然不喜欢迭代所有节点并手动应用原型方法的想法。迭代需要很多时间,并且浏览器在以后调用函数时无法进行太多优化。但您的方法至少不需要为每个节点创建完整副本,也可以处理嵌套/递归节点对象。我修改了代码,完全不使用原型方法,但如果这不是某个人的选择,那么您的解决方案可能是最好的。