深拷贝浅拷贝的区别(记录–一种更现代的深浅拷贝方法)
这里给大家分享我在网上总结出来的一些知识 ,希望对大家有所帮助
你是否知道 ,JavaScript中有一种原生的方法来做对象的深拷贝?
本文我们要介绍的是structuredClone函数 ,它是内置在 JavaScript 运行时中的:
在上面的示例中 ,我们不仅拷贝了对象 ,还拷贝了嵌套数组 ,甚至拷贝了Date对象:
没错 ,structuredClone 不仅可以做到以上这些 ,而且还可以:
克隆无限嵌套的对象和数组 克隆循环引用 克隆各种各样的 JavaScript 类型 ,如 Date, Set, Map, Error, RegExp, ArrayBuffer, Blob, File, ImageData 等等 转移任何可转移的对象举个例子:
为什么不使用对象扩展运算符进行克隆呢
值得注意的是,我们讨论的是深拷贝 。如果你只需要做一个浅拷贝 ,也就是一个不复制嵌套对象或数组的拷贝 ,那么我们可以只做一个对象扩展:
或者你也可以使用这种方法:
但是一旦我们有了嵌套项,我们就会遇到麻烦:
如上所见 ,我们没有对该对象进行完整复制 。
嵌套日期和数组仍然是两者之间的共享引用 ,如果我们想编辑它们,认为我们只是更新复制的日历事件对象 ,这可能会导致重大问题 。
为什么不使用JSON.parse(JSON.stringify(x)) ?
它实际上是一个很棒的工具 ,性能令人惊讶 ,但也有一些structuredClone可以解决的缺点 。
举个例子:
如果我们输出 problematicopy ,我们会得到:
这不是我们想要的 date 格式 ,因为格式应该是date对象 ,而不是字符串 。
这是因为 JSON.Stringify 只能处理基本对象 、数组和基本类型 。任何其他类型都可能以难以预测的方式处理 。例如 ,日期被转换为字符串 。但是 Set 对象就会被简单地转换为 {} 。
同时 ,JSON.Stringify 甚至会完全忽略某些东西 ,如 undefined 或 function。
例如,如果我们用这个方法复制下面这个例子:
输出之后 ,得到的是这样:
可以看到 , 这种方法的拷贝出错了 。
因此,如果我们的需求适合这个方法 ,可以用这个方法 。但是 ,我们可以用 structuredClone 做这个方法有很多不能做的事情。
为什么不是 _.cloneDeep?
到目前为止,Lodash 的 cloneDeep 函数是这个问题的一个非常常见的解决方案 。事实上 ,这确实也像预期的那样工作:
但是 ,这里有一个警告 。根据我的 IDE 中的导入成本扩展 ,打印任何我导入函数的成本 ,这个函数占了 17.4kb` 的大小(5.3kb gzip):
假设你只导入了这个函数。如果改用更常见的方式导入 ,没有意识到摇树并不总是按希望的方式工作 ,那么可能会无意中为这个函数导入高达2 5kb 的文件?
什么是 structuredClone 克隆不了的
函数不能被克隆
DOM 节点不能克隆
属性描述符 setter和getter 不能克隆
类似元数据的特性也不会被克隆 。
例如 ,使用 getter ,结果值会被克隆 ,但不会克隆 getter 函数本身(或任何其他属性元数据):
对象属性不能被克隆
原型链不会被遍历或复制 。因此,如果克隆MyClass的一个实例 ,克隆的对象将不再是该类的实例(但该类的所有有效属性将被克隆)
structuredClone 支持类型的完整列表
更简单地说 ,任何不在下面列表中的东西都不能克隆:
JS 内置类型:Array, ArrayBuffer, Boolean, DataView, Date, Error types (those specifically listed below), Map , Object but only plain objects (e.g. from object literals), Primitive types, except symbol (aka number, string, null, undefined, boolean, BigInt), RegExp, Set, TypedArray
Error types: Error, EvalError, RangeError, ReferenceError , SyntaxError, TypeError, URIError
Web/API types: AudioData, Blob, CryptoKey, DOMException, DOMMatrix, DOMMatrixReadOnly, DOMPoint, DomQuad, DomRect, File, FileList, FileSystemDirectoryHandle, FileSystemFileHandle, FileSystemHandle, ImageBitmap, ImageData, RTCCertificate, VideoFrame
浏览器支持
所有主流浏览器都支持 structuredClone,甚至Node.js和Deno 。
不过在 Web worker 中 ,目前支持是比较有限的 。
本文转载于:
https://juejin.cn/post/7209226686372692029
如果对您有所帮助 ,欢迎您点个关注,我会定时更新技术文档 ,大家一起讨论学习 ,一起进步 。
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!