【JS】大白话 - 深拷贝与浅拷贝 - 及其原生 JS 实现方式
🦖我是 Sam9029,一个前端
Sam9029 的 InfoQ 主页:Sam9029 (infoq.cn)
**🐱🐉🐱🐉恭喜你,若此文你认为写的不错,不要吝啬你的赞扬,求收藏,求评论,求一个大大的赞!👍**
⭐⭐深拷贝与浅拷贝
(仅谈论了 基本数据类型 和 ES5 的引用数据类型 的深拷贝与浅拷贝)
(关于 ES6 及之后 新增的 Symbol,Map 等数据类型还有待谈论)
(以下仅为 原生 JS 的方法,未涉及第三方库使用,第三方库
lodash
也有函数可实现)
❗- 因文字字数原因,涉及的 ⭐对 函数对象 的拷贝(面试常考) 在另一文章中阐述,文章末尾附带地址
注意概念上的区别(很重要):
⭐ 浅拷贝
与 深拷贝 都是需要开辟新内存地址,产生新对象⭐但是
⭐浅拷贝 只拷贝 原始对象中的
最外部一层
⭐深拷贝 则会拷贝 原始对象中
所有的层级
拓展:深浅拷贝与赋值的区别
❗特别 浅拷贝 不是
赋值操作
,这俩就不是一个概念非要整个好活记,深浅拷贝这俩才是 一丘之貉,更本瞧不上赋值
深浅拷贝 主要针对 引用数据类型
赋值 主要是 用于 基本数据类型
当然也可以用于引用数据类型,但此时就要考虑新旧对象的同一引用地址问题了
⭐示例:
对于下面这个 对象
🦊浅拷贝:
只能拷贝属性
name
和age
拥有新地址,但是 拷贝到 info 时 则会引用原始对象 中的地址(!!!即改变原始对象中的
info.desc
的值时,浅拷贝出来的新对象的info.desc
的值同样会改变),属于
不彻底拷贝
,所以 只有一层属性的对象 适合浅拷贝。🦊深拷贝
则可以 完全 拷贝所有层级,变成一个拥有 新地址 的 新对象。属于
彻底的拷贝
改变原始对象的 info.desc 该值也不会影响新对象的
info.desc
的值
浅拷贝:只拷贝最外面一层的数据-(不彻底的拷贝)
一 使用Object.assign
语法:`Object.assign(target,source01,source02,...)`
(将
source对象
中的值 拷贝到target目标对象
中)target
可以写成空对象
注意:若 target 非空 ,且 source 和 target 中有重复属性 ,则 target 中的属性会被覆写;target 的值会被改变, 但是 source 的值不会
示例: (得到新的对象)
示例 (重新赋值给目标对象)
二 使用扩展语法 (...)
使用简单,不必多说
三 for..in 循环拷贝
深拷贝: 每一层数据都会拷贝-(最彻底的拷贝)
一 JSON 方法
语法:
let newObj = JSON.parse(JSON.stringify(obj))
缺陷(暂不谈论,死记,❗重要性高些)
❗会忽略
undefined
会忽略
symbol
❗会忽略函数:
JSON.stringify()
会默认移除函数。JSON.stringify()
无法拷贝Map、Set、RegExp
这些特殊数据类型。不能序列化函数 ???
不能解决循环引用的对象 见[前端进阶之道-深浅拷贝](JS | 前端进阶之道 (yuchengkai.cn))
二 ⭐⭐ JS 有原生的深拷贝 API structuredClone
MDN---structuredClone() - Web 开发技术 | MDN (mozilla.org)](https://developer.mozilla.org/zh-CN/docs/web/api/structuredClone))
结构化拷贝算法的实现,能够实现几乎对所有数据类型的深拷贝
该 API 较新,兼容要考虑(目前主流都支持) ,虽然有些缺点,但是不影响,放心用,以后会加大支持力度
可引入
core-js
兼容库 core-js#structuredclone,兼容旧版本。相比
JSON.parse()
,structuredClone API
的性能更好语法:
缺点:
(死记,放心用,以后会加大支持力度,❗重要性高些)
原型:无法拷贝对象的原型链。
❗函数:无法拷贝函数。(普通函数、箭头函数、类、方法)
❗DOM 节点
不可克隆:并没有支持所有类型的拷贝,比如
Error
。
三 深拷贝 for ... in 手写
优点:(相对的)
可以实现 函数 拷贝
注意其中有些许问题,及函数对象属性并未实现开辟新地址作为新对象,而是引用了原本对象的引用地址来调用
若想要继续了解,请往下看拓展
在深拷贝的前两种实现方式上(JSON,InstructuredClone)都无法对 函数 进行深拷贝,而此种手写的 for-in 方法可以
拓展--对 函数 的 拷贝
在 JS 中 函数 也是一个对象,所以是通过引用地址来调用的
链接🔗:(待写)
参考文章
🦖我是 Sam9029,一个前端,坚信应无所往
文章若有错误,敬请指正🙏
**🐱🐉🐱🐉恭喜你,都看到这了,求收藏,求评论,求一个大大的赞👍!不过分吧**
Sam9029 的 InfoQ 主页:Sam9029 (infoq.cn)
版权声明: 本文为 InfoQ 作者【Sam9029】的原创文章。
原文链接:【http://xie.infoq.cn/article/c1ecd9225333fc4527a0a9a48】。文章转载请联系作者。
评论