在JS中,我们经常会遇到这样一个问题,当我们定义将一个数组或一个对象赋值给变量a后,然后将这个变量a赋值给变量b,修改b的值,我们会发现,a的值也会随着修改,就像这样:
但是一些类型不会,比如string,number, boolean等这种基本类型,这是因为基本类型是按值传递的,也就是说只是将这个变量的数值赋给了另外一个变量,而像array,object这种对象类型是按引用赋值的。
什么是引用?
说的简单一点,就是对计算机中某块内存的引用。
当我们定义一个变量并赋值时,计算机就会在自己的内存中开辟一块空间,以供这个变量使用。拿上一个例子来说,就是这样。
原理分析
1、当我们定义a = [0, 1, 2, 3, 4]时,计算机就在内存中开辟了一块x1234的空间,并将值存储起来,这个时候a其实是对x1234的引用。
2、当我们调用a时,a会去内存中寻找名为x1234的空间。
3、当我们将a赋值给b时,其实是将引用给了b,这个时候b也是对x1234空间的引用,所以修改b的数据的时候,其实是对内存中x1234的修改。
4、再次调用a时,读取的自然也就是修改后的值。这就是浅拷贝的原理。
解决方法
这种问题只在对象类型的变量中会出现问题,在基本类型的变量中不会,那么我们可以考虑将对象类型的变量转化为字符串,然后赋值给另外一个变量再转回对象类型,就像这样。
这只是一种方式,其实有多种方式可以达到深度拷贝的效果,比如ES6的Object.assign(target, …sources),构建对象的方式,手动拷贝方式等。
好了,本次分享就到这里,希望对大家有帮助,以后会专门写一篇文章说说具体实现深度拷贝有哪些方法。