[英]How to check if an object can be cloned by the structured clone algorithm
結構化克隆算法是一種序列化算法,用於通過window.postMessage
在窗口之間傳遞數據。 它支持遞歸對象(與JSON不同),但不支持DOM節點,函數和錯誤等
我想要的是一種檢查給定對象是否可以通過結構化克隆算法序列化的簡單方法。 我可以遞歸地遍歷對象並檢查每個屬性是否是DOM節點,函數或錯誤,但這不是一個完整的答案,我想知道是否有更好的方法。
從規范來看,我認為它會是這樣的
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;
}
}
請注意,這有一些限制:
{}.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;
};
})();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.