javaScript深拷贝和浅拷贝简单梳理
在了解深拷贝和浅拷贝之前,我们先梳理一下:
JavaScript中,分为基本数据类型(原始值)和复杂类型(对象),同时它们各自的数据类型细分下又有好几种数据类型
基本数据类型
数字Number 字符串String 布尔Boolean Null Undefined Symbols BigInt
基本数据类型在内存当中,是存储在栈Stack
在数据结构当中
- 栈在内存上的分配的空间生命周期很短,当变量使用完毕,方法执行完成就被释放掉,因此在js当中,变量使用完毕之后,基本就被回收了,
- 有一个场景比较例外,闭包的情况下,变量是始终存在内存当中不被释放.
- 栈存储具有先进后出,后进先出的特点: 1,2,3,4,5,6 => 6,5,4,3,2,1
引用数据类型
日期Dete,对象Object,数组Array,方法Function, 正则regex,带键的集合:Maps, Sets, WeakMaps, WeakSets
引用数据类型与堆内存heap的一些关系
- 在JavaScript中,不允许直接访问堆内存中的位置,不能直接操作对象的堆内存空间。
- 对象的引用地址是存在栈内存中,在我们的日常编码过程中,操作对象的时候,读取对象的存在栈内存的引用地址而不是在堆中的对象,引用类型的值都是通过引用访问。
JavaScript中堆内存和栈内存简易示意图例

下面对于对象的操作,都可以参照上图进行思考
浅拷贝-深拷贝
浅拷贝
只是拷贝了某一层的属性,或者某一层,没有全部拷贝到另外的对象上
let userInfo = {
name: "zhangsan",
age: "29",
say: function () {
console.log("hello");
},
child: [
{
name: "zhangsan01",
},
],
};
- 对象解构,只能拷贝第一层对象
// 对象解构...
let info = { ...userInfo };
info.name = "lisi";
info.child.name = "lisi001";
info.say();
console.log("userInfo", userInfo);
console.log("info", info);
userInfo和info中的child.name都改成了---->"lisi001"
- Object.assign() 第一层是深拷贝,二级属性后就是浅拷贝
let info = {};
Object.assign(info, userInfo);
info.name = "lisi";
info.child.name = "lisi001";
console.log("userInfo", userInfo);
console.log("info", info);
- JSON.parse(JSON.stringify());
对象可以复制,但是当属性是function时,没有复制到新的对象上,因此在日常的开发过程中,涉及到数组对象,使用JSON.parse(JSON.stringify());还是没问题的
let info = JSON.parse(JSON.stringify(userInfo));
info.name = "lisi";
info.child.name = "lisi001";
console.log("userInfo", userInfo);
console.log("info", info);
- for in,第一层可以拷贝,第二层在修改的时候,还是使用的引用地址,前后的对象都发生了更改
let info = {};
for (let key in userInfo) {
info[key] = userInfo[key];
}
info.name = "lisi";
info.child.name = "lisi001";
console.log("userInfo", userInfo);
console.log("info", info);
浅拷贝小结
以上浅拷贝方法,有些拷贝只能拷贝第一层,有些可以拷贝多层,
但是当属性类型是方法时,还是浅拷贝,
因此我们在开发中,使用浅拷贝,需要注意,同时,出了拷贝function,类似正则,date等数据类型没有一一列举,感兴趣的同学可以自己写一些demo,去校验更为复杂和数据类型更丰富的数据。
深拷贝
所有的属性都拷贝到新的对象上
- 使用递归遍历每一个属性,在递归遍历的时候,针对每一种数据类型处理和拷贝
- lodash深拷贝方法,感兴趣的同学,可以去阅读lodash深拷贝的实现源码
文档地址:深拷贝cloneDeep https://www.lodashjs.com/docs/lodash.cloneDeep
- 更多方法,有待补充
结尾
当我们操作复杂数据类型的时候,都是在操作栈内存Stack的内存地址,指针指向对象在堆内存heap的数据。
传入的对象是使用对象字面量{}创建的对象还是由构造函数生成的对象
如果对象是由构造函数创建出来的,那么是否要拷贝原型链上的属性
如果要拷贝原型链上的属性,那么如果原型链上存在多个同名的属性,保留哪个
针对的数据类型,属性的数据类型,各自的缺陷,适用的业务场景,自己造轮子or使用原生方法,工具类
源码地址
文章个人博客地址:javaScript中深拷贝和浅拷贝梳理
欢迎关注公众号:程序猿布欧,不定期更新一些前端入门文章
创作不易,转载请注明出处和作者。
javaScript深拷贝和浅拷贝简单梳理的更多相关文章
- javascript 深拷贝与浅拷贝
javascript 深拷贝与浅拷贝 深拷贝与浅拷贝 赋值和深/浅拷贝的区别 浅拷贝的实现方式 1.Object.assign() 2.函数库lodash的_.clone方法 3.展开运算符... 4 ...
- 读懂javascript深拷贝与浅拷贝
1. 认识深拷贝和浅拷贝 javascript中一般有按值传递和按引用传递两种复制,按值传递的是基本数据类型(Number,String,Boolean,Null,Undefined),一般存放于内存 ...
- JavaScript深拷贝与浅拷贝的区别和实现方式
如何区分深拷贝和浅拷贝呢,简单来说对象B拷贝了对象A,如果对象A和对象B共用一个对象,对象B改变对象A跟着改变这就是浅拷贝:但如果对象B拷贝了对象A,但是对象A和对象B是分开的,那么就是深拷贝 基本数 ...
- JavaScript深拷贝与浅拷贝的理解
个人是这么理解深拷贝和浅拷贝的:就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力. 一起看看我举的浅拷贝栗子: let ...
- javaScript 深拷贝、浅拷贝
在 JS 中有一些基本类型像是Number.String.Boolean,而对象就是像这样的东西{ name: 'Larry', skill: 'Node.js' },对象跟基本类型最大的不同就在于他 ...
- JavaScript深拷贝和浅拷贝
1. 基本类型 和 对象类型 他们最大的区别就是在于他们的传值方式. 基本类型是传值 对象类型就是传引用. 这里复制一份obj叫做obj2, 这里修改了obj2的b为100 同时也修改了obj1.b. ...
- JS JavaScript深拷贝、浅拷贝
浅拷贝:浅拷贝只是复制了内存地址,如果原地址中的对象改变了,浅拷贝出来的对象也会相应改变. 深拷贝:开辟了一块新的内存存放地址和地址指向的对象,原地址的任何对象改变了,深拷贝出来的对象不变. 浅拷贝数 ...
- 也来玩玩 javascript对象深拷贝,浅拷贝
经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One method of copying an object is ...
- javascript对象深拷贝,浅拷贝 ,支持数组
javascript对象深拷贝,浅拷贝 ,支持数组 经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One meth ...
随机推荐
- Windows10与Centos7双系统安装踩的坑
1. 首先安装windows(太简单不说了) 2.然后安装Centos7(太简单不说了) 3.注意:安装完Centos7重启电脑进入系统引导项突然发现没有Windows引导项 0x06 恢复Windo ...
- java中会存在内存泄漏吗,请简单描述?
所谓内存泄露就是指一个不再被程序使用的对象或变量一直被占据在内存中.java中有垃圾回收机制,它可以保证一对象不再被引用的时候,即对象编程了孤儿的时候,对象将自动被垃圾回收器从内存中清除掉.由于Jav ...
- 为什么线程通信的方法 wait(), notify()和 notifyAll()被定 义在 Object 类里?
Java 的每个对象中都有一个锁(monitor,也可以成为监视器) 并且 wait(),notify() 等方法用于等待对象的锁或者通知其他线程对象的监视器可用.在 Java 的线程中 并没有可供任 ...
- Redis Set Type
集合中的元素个数最多为2的32次方-1个,集合中的元素师没有顺序的. Redis集合的操作命令和对应的api如下: smembers [set] JedisAPI:public Set<Stri ...
- ACL 权限控制机制 ?
UGO(User/Group/Others) 目前在 Linux/Unix 文件系统中使用,也是使用最广泛的权限控制方式.是一种粗 粒度的文件系统权限控制模式. ACL(Access Control ...
- IPhoneX网页布局简介
IPhoneX全面屏是十分科技化的,但是由于其圆角和摄像头刘海位置以及操控黑条的存在使得我们需要去对其样式做一些适配,没有X的同学可以开启 Xcode 9 的iPhone X 模拟器作为学习和调试. ...
- 对Flex布局的总结与思考
阅读本文之前最好对flex布局有基本了解,可以通过"参考资料"中列举的资源来学习. flex布局规范的设计目标 一维布局模型(one-dimensional layout mode ...
- SphinxJS——把字符串编码成png图片的超轻量级开源库
体验地址:https://jrainlau.github.io/sp...项目地址:https://github.com/jrainlau/s... SphinxJS 一个能够把字符串编码成png图片 ...
- css3中user-select的用法详解
css3中user-select的用法详解 user-select属性是css3新增的属性,用于设置用户是否能够选中文本.可用于除替换元素外的所有元素,以下是user-select的主要用法和注意事项 ...
- ubantu14.04搜狗拼音安装
1. 先卸载fcitx: sudo apt-get purge fcitx*2. 安装fcitx和libssh2-1: sudo apt-get install fcitx 和 sudo apt-ge ...