不管是实际应用还是面试当中,js的深拷贝和浅拷贝的区别一直都是最常遇到的问题,今天花点时间彻底搞定它。
相关知识点
1. js两种不同的数据类型
- 基本类型:String,Boolean,Number,Undefined,Null;
- 引用类型:Object(Array,Date,RegExp,Function);
两者最大的区别就是保存位置的不同,基本数据类型是保存在栈内存里;引用数据类型是保存在堆内存里,然后在堆内存里保存一个对堆内存的引用(类似于指针)。
2. js变量的存储方式
- 栈内存:自动分配内存空间,系统自动释放,里面存放的是基本类型的值和引用类型的地址
- 堆内存:动态分配的内存,大小不定,也不会自动释放。里面存放引用类型的值
为什么两种数据类型保存不同?
- 堆比栈大,栈比堆速度快;
- 基本数据类型比较稳定,而且相对来说占用的内存小;
- 引用数据类型大小是动态的,而且是无限的,引用值的大小会改变,不能把它放在栈中,否则会降低变量查找的速度,因此放在变量栈空间的值是该对象存储在堆中的地址,地址的大小是固定的,所以把它存储在栈中对变量性能无任何负面影响;
- 堆内存是无序存储,可以根据引用直接获取
浅拷贝和深拷贝
**简单的解释:**浅拷贝只复制了某个对象的引用(指针),新旧对象还是共享一片内存;但是深拷贝会创造一个一模一样的对象,对原对象的属性进行递归复制。
1.浅拷贝
1.赋值
最容易遇到的情况,最开始
var obj = { a : 0, b : 1 }
var obj2 = obj
obj2.a = 2
console.log(obj.a, obj2.a) // 2, 2
2.深拷贝
1.使用JSON.stringify和JSON.parse实现深拷贝:JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象;
var obj3 = JSON.parse(JSON.stringify(obj))