如何检查一个对象是否可以通过结构化克隆算法克隆
How to check if an object can be cloned by the structured clone algorithm
结构化克隆算法是一种序列化算法,用于通过window.postMessage
在窗口之间传递数据。它支持递归对象(与JSON不同),但不支持DOM节点、函数和错误等
我想要的是一个简单的方法来检查一个给定的对象是否可以被结构化克隆算法序列化。我可以递归遍历对象并检查每个属性是否为DOM Node、Function或Error,但这不是一个完整的答案,我想知道是否有更好的方法。
从规范来看,我认为应该是
function canBeCloned(val) {
if(Object(val) !== val) // Primitive value
return true;
switch({}.toString.call(val).slice(8,-1)) { // Class
case 'Boolean': case 'Number': case 'String': case 'Date':
case 'RegExp': case 'Blob': case 'FileList':
case 'ImageData': case 'ImageBitmap': case 'ArrayBuffer':
return true;
case 'Array': case 'Object':
return Object.keys(val).every(prop => canBeCloned(val[prop]));
case 'Map':
return [...val.keys()].every(canBeCloned)
&& [...val.values()].every(canBeCloned);
case 'Set':
return [...val.keys()].every(canBeCloned);
default:
return false;
}
}
注意这有一些限制:
- 我无法检查对象是否有[[DataView]]内部插槽
-
{}.toString
不是获得[[Class]]的可靠方法,但却是唯一的方法。 - 其他规范可以定义如何克隆其他类型的对象
因此,尝试运行算法,看看是否会产生一些错误,可能更可靠:
function canBeCloned(val) {
try {
window.postMessage(val,'*');
} catch(err) {
return false;
}
return true;
}
注意,如果您有一个message
事件监听器,它将被调用。如果您想避免这种情况,请将该值发送到另一个窗口。例如,您可以使用iframe创建一个:
var canBeCloned = (function() {
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
var win = iframe.contentWindow;
document.body.removeChild(iframe);
return function(val) {
try { win.postMessage(val, '*'); }
catch(err) { return false; }
return true;
};
})();
相关文章:
- jquery动画可以通过编程链接吗
- 在Highcharts中,我们可以通过任何方式在渲染图表之前获得plotWidth和plotHeight
- 我可以通过JQuery将CSS类交换为一个特殊的元素集吗
- 是否可以通过Chrome扩展内容脚本打开Chrome外部协议请求
- 有没有一种方法可以通过只引用JavaScript来执行代码
- 当一些事情可以通过JS或CSS完成时,我应该选择哪种方式
- 响应式图片库,每个图片都可以通过锚链接访问
- window.open:是否可以通过修改DOM来打开一个新窗口
- 可以通过ClassName在多个画布上绘制
- 我们可以在初始化variable Angular JS时将变量值声明为未定义吗
- 我可以通过点击html文件中的按钮来记录我的屏幕/网页吗
- ES6非结构化中的计算属性-非结构化整体对象
- 如何解析文本区域中的结构化字符串数据(接近JSON)以检索其所需的属性
- 为什么无法根据谷歌地图地理编码geometry.bounds找到位置,但可以通过MongoDB中的geometry.vi
- 有没有什么方法可以通过输入字段(type=file)来找出选择了多少个文件
- 是否可以通过Primefaces 3.3的自定义对话框取消Ajax请求
- 有没有一种正确的方法可以通过jQuery构建HTML
- 我可以通过javascript在鼠标光标旁边动态添加文本吗?
- 结构化功能.可以't在现有代码中添加if语句
- 如何检查一个对象是否可以通过结构化克隆算法克隆