如上图,据描述,Object.assign()为浅拷贝, 为什么改变属性a不是指向同一个引用,而b.c指向了同一个引用?
首先,都是浅拷贝。第一种数据存放基本类型,数组中存放的就是基本类型的值,拷贝的就是基本类型的值,第二种存放的是对象,存放的是对象的地址,拷贝的就是对象的地址。
看一张图吧,你应该就可以明白了。
高级语言都是相通的,浅copy指的是arr1, arr身份不同,但是每个项目引用的对象还是同一个,所以当你push的时候,是放到了arr1的地址空间中,而修改{a:1}时,arr1和 arr2都引用了该对象,所以自然就都修改了。
javascript分原始类型与引用类型(与java、c#类似)。Array是引用类型,直接用“=”号赋值的话,只是把源数组的地址(或叫指针)赋值给目的数组,并没有实现数组的数据的拷贝。这种方式的实现属于浅拷贝。
对一维数组和多维数据的深拷贝实现方式是不一样的。
一、一维数组的实现方式:
使用slice() 或者 concat()来实现一维数组的深拷贝,但这种方法只适用于一维数组,对多维数组无效。
arrayObj.slice(start,[end]):
可使用slice()进行复制,因为slice()返回也是数组。slice方法是通过参数start和end的传入值来返回数组中的一段,该方法不对原数组进行操作。slice(0)代表返回所有项。
var array1 = new Array("1","2","3");
var array2;
array2 = array1.slice(0);
array1.length = 0;
alert(array2); //返回1、2、3
首先涉及到一个 基本类型还是引用类型,
基本类型的话就是相当于就是赋值给新的变量,相当于把值完全赋值过去,新的变量改变不会影响旧的变量,他们两者都占有不同的位置但是相等的内存空间
而引用数据类型:存放在堆区对象中,变量存储的是再一个指针地址中,你将赋值于一个新变量的时候, 值保存的还是在同一个地址
jquey中的$.extend({}, obj); Array.prototype.slice()和Array.prototype.concat()都会返回一个数组或者对象的浅拷贝。(看起来像深拷贝)