-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
面试官:深拷贝浅拷贝的区别?如何实现一个深拷贝? #56
Comments
作者你好,请问一下 |
@zero2015 当prop属性存在于原型链上时,并不是obj自身属性的时候 |
因为 hasOwnProperty 并不是保留的关键字,所以如果对象上有 hasOwnProperty 作为属性名的时候,obj.hasOwnProperty(prop) 还有可能会报错 obj.hasOwnProperty is not a function 所以应该用 Object 上真正的 hasOwnProperty 方法 |
既然slice 和concat 实现的是浅拷贝 那为什么改变其中一个另外一个不变呢? concat 方法返回一个新的数组,不会影响到原数组 这不是深拷贝的意思吗 |
不知道你说的是不是对于数字或者字符串的情况。对于原始值(数字、字符串)来说,浅拷贝和深拷贝是一样的,都是对值的拷贝,拷贝出来是独立的两个值;而对于引用类型来说(对象),浅拷贝拷贝的是值的引用,这个时候才会导致改了一个另外一个也变化。 |
扩展运算符是深拷贝吧,只能拷贝一层 |
浅拷贝只是复制了内存指引,最终指向的内存地址还是同一个,所以当发生变化的时候,所有的相关引用都会变,因为指向的是同一个对象, |
难道深拷贝的时候不考虑循环引用的问题吗? |
要不要试试这个方法 window.structuredClone 🚀🚀🚀 |
手写拷贝, obj == null 不是 obj === null |
你没清楚for in |
Object.assign 生成的新对象,使用严格比较。结果为FALSE, 它不是浅拷贝吗 |
slice concat和...不都是深拷贝吗? |
如果数组中元素是对象,你试下 |
一、数据类型存储
前面文章我们讲到,
JavaScript
中存在两大数据类型:基本类型数据保存在在栈内存中
引用类型数据保存在堆内存中,引用数据类型的变量是一个指向堆内存中实际对象的引用,存在栈中
二、浅拷贝
浅拷贝,指的是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝
如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址
即浅拷贝是拷贝一层,深层次的引用类型则共享内存地址
下面简单实现一个浅拷贝
在
JavaScript
中,存在浅拷贝的现象有:Object.assign
Array.prototype.slice()
,Array.prototype.concat()
Object.assign
slice()
concat()
拓展运算符
三、深拷贝
深拷贝开辟一个新的栈,两个对象属完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性
常见的深拷贝方式有:
_.cloneDeep()
jQuery.extend()
JSON.stringify()
手写循环递归
_.cloneDeep()
jQuery.extend()
JSON.stringify()
但是这种方式存在弊端,会忽略
undefined
、symbol
和函数
循环递归
四、区别
下面首先借助两张图,可以更加清晰看到浅拷贝与深拷贝的区别
从上图发现,浅拷贝和深拷贝都创建出一个新的对象,但在复制对象属性的时候,行为就不一样
浅拷贝只复制属性指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存,修改对象属性会影响原对象
但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象
小结
前提为拷贝类型为引用类型的情况下:
浅拷贝是拷贝一层,属性为对象时,浅拷贝是复制,两个对象指向同一个地址
深拷贝是递归拷贝深层次,属性为对象时,深拷贝是新开栈,两个对象指向不同的地址
The text was updated successfully, but these errors were encountered: