admin管理员组文章数量:1435859
The structured clone algorithm is a serialization algorithm used, among other things, to pass data between windows via window.postMessage
. It supports recursive objects (unlike JSON) but not things like DOM Nodes, Functions, and Errors, and other
What I'd like is a simple way to check if a given object can be serialized by the structured clone algorithm. I could recursively walk the object and check if each property is a DOM Node, Function, or Error, but that's not a plete answer, and I was wondering if there was a better way.
The structured clone algorithm is a serialization algorithm used, among other things, to pass data between windows via window.postMessage
. It supports recursive objects (unlike JSON) but not things like DOM Nodes, Functions, and Errors, and other
What I'd like is a simple way to check if a given object can be serialized by the structured clone algorithm. I could recursively walk the object and check if each property is a DOM Node, Function, or Error, but that's not a plete answer, and I was wondering if there was a better way.
Share Improve this question asked Sep 19, 2015 at 21:42 RetsamRetsam 33.5k11 gold badges72 silver badges94 bronze badges 3-
5
Why not try, then catch the
DATA_CLONE_ERR
exception that it throws if it's not valid? If you catch an exception, the object is not serializable, otherwise it is. – Maximillian Laumeister Commented Sep 19, 2015 at 21:48 -
1
The API doesn't always use
window.postMessage
depending on the context, but for consistency I'd like it to report an error if the data isn't patible with the structured clone algorithm. – Retsam Commented Sep 19, 2015 at 22:20 - 1 Try/catch should work fine in that case too. – Maximillian Laumeister Commented Sep 19, 2015 at 22:23
1 Answer
Reset to default 5From the spec, I think it would be something like
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;
}
}
Note this has some limitations:
- I can't check if an object has a [[DataView]] internal slot
{}.toString
is not a reliable way to get the [[Class]], but is the only one.- Other specifications may define how to clone additional kinds of objects
So it may be more reliable to attempt to run the algorithm, and see if it produces some error:
function canBeCloned(val) {
try {
window.postMessage(val,'*');
} catch(err) {
return false;
}
return true;
}
Note if you have a message
event listener, it will be called. If you want to avoid this, send the value to another window. For example, you can create one using an 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;
};
})();
本文标签: javascriptHow to check if an object can be cloned by the structured clone algorithmStack Overflow
版权声明:本文标题:javascript - How to check if an object can be cloned by the structured clone algorithm - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745674990a2669798.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论