一、拷贝是干嘛的
“拷贝” 字面上的意思,我们又叫它复制,js中也一样,对于数据的复制
- 不过这个复制是:与 引用数据类型 的相关复制
什么是引用数据类型?
数据类型的介绍文章链接
-
数据类型:
-
基本数据类型:数值(number)、字符串(string)、布尔(Boolean)、null、undefined
-
复杂数据类型:对象(object)、构造函数(function)、数组(array)
复杂数据类型 又称为 引用数据类型
-
-
引用数据类型的特性:
- 引用类型的值是可变的
- 引用类型的值是同时保存在栈内存和堆内存中的对象
- 引用类型的比较是引用(地址)的比较
二、拷贝的介绍
拷贝分为浅拷贝和深拷贝
浅拷贝
只是简单的复制拷贝 引用数据类型的地址
地址相同的变量,操作引用数据类型,彼此都会有影响
let arr1 = [1,2,3,4,5];
let arr2 = arr1;
此时,复制的是arr1中数组的地址,arr2和arr1是相同的地址,指向相同的数组
如果数组中的值发生改变,那么arr2获取到的内容也会发生或改变
举个栗子:
- a和b同时合租一处房子,他们都有这个房子的钥匙,那么这个钥匙就是地址,一天,a生气把屋子里的电视机砸了,那么b回到家就会发现一个坏掉的电视机
深拷贝
完整的复制拷贝一个引用数据类型中的数值数据到另一个引用数据类型中
两个变量:是两个的独立的引用数据类型、是两个独立的存储空间
一个变量操作引用数据类型 不会影响另一个变量
let arr3 = [1,2,3,4,5];
let arr4 = [];
arr3.forEach(function(item){ //遍历arr3中的数据
arr4.push(item); //将遍历到的数据一个一个的复制到arr4里面
})
arr4[0] = '你好';
console.log(arr3); 此时arr3 = ['你好',2,3,4,5]
console.log(arr4); 此时arr4 = [1,2,3,4,5]
再拿个栗子:
a盖了一个漂亮的房子,b看了非常羡慕,然后就把a的房子里里外外看了个遍,然后盖了一个一模一样的房子(连摆放的家具都一模一样),这时a又把家里。的电脑砸坏了,那么b家里的电脑是不可能原力坏掉的。
三、拷贝重要内容:
多维数组或者对象中存储对象/数组,也就是引用数据类型中,再次存储引用数据类型
我们通常叫它嵌套
let arr5 = [ 1,2,3,[4,5,6,[7,8,9,[10,11,12]]]]
- 原生JavaScript中用递归函数来实现解决(比较复杂)
- 在jQuery中,提供了专门的方法来实现 深浅拷贝/深浅复制
jQuery实现深浅拷贝
方法:$.extend()
语法形式1:$.extend( 是否深拷贝(不写) , 对象1,对象2,对象3…) 浅拷贝
语法形式2:$.extend( 是否深拷贝(true) , 对象1,对象2,对象3…) 深拷贝
怎么拷贝:将对象2、对象3等的引用数据类型,拷贝复制到 对象1中
浅拷贝
var obj1 = { name1:'张三1',age1:18 , sex:'男'};
var obj2 = { name2:'张三2',age2:19 , sex:'女',data:{time:123} };
$.extend(obj1,obj2); //这里执行的是浅拷贝
obj2.data.time = 456; //我们在这里改变obj2里面引用数据类型的值
console.log(obj1);
console.log(obj2);
结果:
深拷贝:
var obj1 = { name1:'张三1',age1:18 , sex:'男'};
var obj2 = { name2:'张三2',age2:19 , sex:'女',data:{time:123} };
$.extend(true ,obj1,obj2 ); //深拷贝
obj2.data.time = 456; //修改
console.log(obj1);
console.log(obj2);
结果:
总结:
对于 复制内容 来说 ,如果是字符串等 基本数据类型,不会被影响、修改
对于 复制内容 来说 ,如果是引用数据类型中的数据,要考虑是否要执行深浅拷贝
键名相同的 复制拷贝 , 后面的数据会覆盖之前的数据,是重复赋值的效果