浅拷贝和深拷贝 与 引用数据类型 的复制相关
1、浅拷贝
只是简单的复制拷贝引用数据类型的地址
地址相同的变量,操作引用数据类型,彼此都会有影响
<script type="text/javascript">
let arr1 = [1,2,3,4];
let arr2 = arr1;
arr2[0] = '北京';
console.log(arr1);
console.log(arr2);
</script>
arr1 中存储的是数组的内存地址
arr2 中存储 的是 arr1 中 存储的数组的内存地址
arr2 和 arr1 中存储的是相同的内存地址 ,指向的是同一个数组
如果 arr1 或者 arr2 对 这个数组做出修改,都会影响另一个变量的输出
此时通过arr2[0]=‘北京’,修改了数组数据,arr1,arr2的结果都改变了
2、深拷贝
完整的复制拷贝 一个引用数据类型中的数据,到另一个引用数据类型中
两个变量是两个 独立的 引用数据类型 是两个独立的存储空间
一个变量操作 引用数据类型 不会影响另一个变量
<script type="text/javascript">
let arr1 = [1,2,3,4];
let arr2 =[];
arr1.forEach(function(item){
arr2.push(item);
})
arr2[0] = '北京';
console.log(arr1);
console.log(arr2);
</script>
通过循环遍历,获取 arr1中的所有数值,复制拷贝在arr2中
此时 arr2 与 arr1 虽然数值相同,但是是两个独立的引用数据类型,是两个独立的空间
因此 arr2或者arr1,修改数组数据,不会对另一个引用数据类型造成影响
arr2 在 复制完 arr1 中的数据后,通过arr2[0]=‘北京’,修改了自己所引用的数组内容,跟arr1无关
所以 arr2 结果改变,arr1结果不变
关键问题是 多维数组,或者是对象中存储对象,也就是引用数据类型中,再次存储引用数据类型的深浅拷贝
不能只是单纯的复制拷贝引用类型的地址,必须再次解析引用类型中的具体数值
还必须再按照原有的嵌套方式,将结构 拷贝至 新的引用数据类型
原生JavaScript中用递归函数来实现解决
在jQuery中,提供了专门的方法来实现 引用数据类型中,再次存储引用数据类型深浅拷贝
$.extend()方法
语法形式1: $.extend( 是否深拷贝(不写) , 对象1,对象2,对象3...)
执行的是浅拷贝
语法形式2: $.extend( 是否深拷贝(true) , 对象1,对象2,对象3...)
执行的是深拷贝
将对象2,对象3,等之后的引用数据类型,拷贝复制到 对象1中
使用 extend()方法来 完成 拷贝
对于 拷贝内容 来说, 如果是字符串等基本数据类型修改,不会被影响
如果是引用数据类型中的数据,要考虑是否要执行深浅拷贝
键名相同的拷贝 , 后面的数据会覆盖之前的数据
这里我们通过对象类型来说明$.extend()方法的使用
浅拷贝
<script type="text/javascript">
let obj1 = {
name1: '张三1',
age1: 18,
sex: '男'
};
let obj2 = {
name2: '张三2',
age2: 19,
sex: '女',
body: {
weight: 90
}
};
// 没有写第一个参数true,是浅拷贝
$.extend(obj1,obj2);
obj2.name2 = '李四';
obj2.boay.weight = 456;
console.log(obj1); // obj1 中的 name2 没有改变,weight 改变
console.log(obj2);
</script>
深拷贝
<script type="text/javascript">
let obj1 = {
name1: '张三1',
age1: 18,
sex: '男'
};
let obj2 = {
name2: '张三2',
age2: 19,
sex: '女',
body: {
weight: 90
}
};
// 有第一个参数true,是深拷贝
$.extend(true ,obj1,obj2 );
obj2.name2 = '李四';
obj2.boay.weight = 100;
console.log(obj1); // obj1 中的 name2 没有改变,weight 也没有改变
console.log(obj2);
</script>