Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/373.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 如何检查结构化克隆算法是否可以克隆对象_Javascript_Structured Clone - Fatal编程技术网

Javascript 如何检查结构化克隆算法是否可以克隆对象

Javascript 如何检查结构化克隆算法是否可以克隆对象,javascript,structured-clone,Javascript,Structured Clone,是一种序列化算法,用于通过window.postMessage在窗口之间传递数据。它支持递归对象(与JSON不同),但不支持DOM节点、函数和错误等 我想要的是一种简单的方法来检查给定对象是否可以通过结构化克隆算法序列化。我可以递归地遍历对象并检查每个属性是否是DOM节点、函数或错误,但这不是一个完整的答案,我想知道是否有更好的方法。从 功能可克隆(val){ if(Object(val)!==val)//原语值 返回true; 开关({}.toString.call(val.slice(8,-

是一种序列化算法,用于通过
window.postMessage
在窗口之间传递数据。它支持递归对象(与JSON不同),但不支持DOM节点、函数和错误等

我想要的是一种简单的方法来检查给定对象是否可以通过结构化克隆算法序列化。我可以递归地遍历对象并检查每个属性是否是DOM节点、函数或错误,但这不是一个完整的答案,我想知道是否有更好的方法。

功能可克隆(val){
if(Object(val)!==val)//原语值
返回true;
开关({}.toString.call(val.slice(8,-1)){//Class
案例“布尔”:案例“编号”:案例“字符串”:案例“日期”:
案例“RegExp”:案例“Blob”:案例“FileList”:
案例“ImageData”:案例“ImageBitmap”:案例“ArrayBuffer”:
返回true;
案例“数组”:案例“对象”:
返回Object.keys(val).every(prop=>canBeCloned(val[prop]));
案例“地图”:
返回[…val.keys()].every(可克隆)
&&[…val.values()].every(可克隆);
案例“集合”:
每返回[…val.keys()]。(可克隆);
违约:
返回false;
}
}
注意,这有一些限制:

  • 我无法检查对象是否有[[DataView]]内部插槽
  • {}.toString
    不是获取[[Class]]的可靠方法,但却是唯一的方法
  • 其他规范可能会定义如何克隆其他类型的对象
因此,尝试运行该算法并查看是否会产生一些错误可能更可靠:

功能可克隆(val){
试一试{
window.postMessage(val,“*”);
}捕捉(错误){
返回false;
}
返回true;
}
注意:如果您有一个
消息
事件侦听器,它将被调用。如果要避免这种情况,请将该值发送到另一个窗口。例如,可以使用iframe创建一个:

var可以克隆=(函数(){
var iframe=document.createElement('iframe');
document.body.appendChild(iframe);
var win=iframe.contentWindow;
document.body.removeChild(iframe);
返回函数(val){
试试{win.postMessage(val,'*');}
catch(err){return false;}
返回true;
};
})();

为什么不试试,然后捕获它在无效时抛出的
数据克隆错误
异常?如果捕获到异常,则对象不可序列化,否则可序列化。API并不总是使用
window.postMessage
,具体取决于上下文,但为了保持一致性,如果数据与结构化克隆算法不兼容,我希望它报告一个错误。在这种情况下,Try/catch也可以正常工作。我不认为对象的
|val instanceof
符合您的预期do@Bergi确实,大多数宿主对象在原型链中都有
对象.prototype
。规范中说“如果输入是一个
对象
对象”,不确定这是否意味着[[Prototype]]必须是
对象。Prototype
,或者[[Class]
“Object”
是的,在条件列表下面提到它们意味着
[[Class]]
可能对“试一试”方法也很有用,虽然如果在克隆失败时不采取措施避免向控制台发送带有错误消息的垃圾邮件,这种方法可能会有问题……如果对象包含循环引用,该函数不会溢出堆栈吗?