深拷贝和浅拷贝,也叫做深层次复制和浅层次复制
如对数组或者对象进行拷贝:
浅拷贝原理:只是将数组的内存地址复制给另一个变量,实际还是同一个内存地址空间,对任何一个变量修改元素,都是在修改同一个内存地址空间中的元素,不管是哪个变量中的元素都发生了改变
例:将arr1赋值给arr2,实际是将arr1中存储的数组的内存地址赋值给了arr2,不管对arr1操作还是对arr2操作,他们改变的都是同一个内存空间中的元素,如改变的是arr2中下标为0的元素,但实际arr1中下标为0的元素也改变了,这就是浅拷贝
let arr1 = [1, 2, 3, 4, 5];
let arr2=arr1;
arr2[0]=“老王”;
深拷贝原理:重新创建一个数组空间,将另一个空间中的元素循环复制到新空间中,这实际是两个独立的空间,对一个空间中的元素进行操作,另一个空间中的元素不会受到影响
例:arr3是一个新的数组空间,将arr1中的数组元素循环遍历插入到数组arr3中,这就实现了深拷贝,对arr3中的元素进行改变,arr1中的元素不会发生改变
let arr3 = [];
arr1.forEach(function(item) {
arr3.push(item);
});
arr3[0] = “老李”;
上述中的深浅拷贝都是对一位数组或者对象进行拷贝,而对多维数组或者对象进行拷贝,不能只是将对应数组的内存地址复制过来,而是要将其中的内容和嵌套方式原模原样复制出来,在原生JavaScript中用递归函数来解决多维数组或者对象的深浅拷贝,其方法比较麻烦,而在jQuery中有专门的的方法实现深浅拷贝,其方法是
.
e
x
t
e
n
d
(
)
,
括
号
中
可
以
存
储
多
个
引
用
数
据
类
型
的
对
象
,
其
实
现
效
果
是
将
除
对
象
1
后
面
的
所
有
对
象
中
的
元
素
复
制
拷
贝
给
对
象
1
。
注
意
:
使
用
e
x
t
e
n
d
(
)
方
法
进
行
拷
贝
,
如
果
需
要
复
制
的
内
容
是
字
符
串
等
基
本
数
据
类
型
,
复
制
的
内
容
改
变
不
会
影
响
原
对
象
的
内
容
,
如
果
复
制
内
容
是
引
用
数
据
类
型
中
的
数
据
,
就
会
出
现
浅
拷
贝
和
深
拷
贝
的
问
题
。
同
时
还
要
注
意
,
如
果
复
制
内
容
中
有
相
同
的
键
名
,
则
后
面
的
数
据
会
覆
盖
前
面
的
数
据
,
同
一
个
键
名
只
会
出
现
一
次
。
如
果
.extend(),括号中可以存储多个引用数据类型的对象,其实现效果是将除对象1后面的所有对象中的元素复制拷贝给对象1。 注意:使用 extend()方法进行拷贝,如果需要复制的内容是字符串等基本数据类型,复制的内容改变不会影响原对象的内容,如果复制内容是引用数据类型中的数据,就会出现浅拷贝和深拷贝的问题。同时还要注意,如果复制内容中有相同的键名,则后面的数据会覆盖前面的数据,同一个键名只会出现一次。 如果
.extend(),括号中可以存储多个引用数据类型的对象,其实现效果是将除对象1后面的所有对象中的元素复制拷贝给对象1。注意:使用extend()方法进行拷贝,如果需要复制的内容是字符串等基本数据类型,复制的内容改变不会影响原对象的内容,如果复制内容是引用数据类型中的数据,就会出现浅拷贝和深拷贝的问题。同时还要注意,如果复制内容中有相同的键名,则后面的数据会覆盖前面的数据,同一个键名只会出现一次。如果.extend()的括号中第一个元素是true,则进行深拷贝,true后面的第一个元素是对象1,其语法是:
.
e
x
t
e
n
d
(
t
r
u
e
,
对
象
1
,
对
象
2
,
对
象
3...
)
如
果
括
号
中
第
一
个
元
素
不
是
t
r
u
e
,
则
进
行
浅
拷
贝
,
其
语
法
是
:
.extend(true , 对象1,对象2,对象3...) 如果括号中第一个元素不是true,则进行浅拷贝,其语法是:
.extend(true,对象1,对象2,对象3...)如果括号中第一个元素不是true,则进行浅拷贝,其语法是:.extend( 对象1,对象2,对象3…)
例:let obj1 = { name1:‘张三1’,age1:18 , sex:‘男’};
let obj2 = { name2:‘张三2’,age2:19 , sex:‘女’,data:{time:123} };
浅拷贝:将对象obj2中的数据复制给obj1,接着对obj2中的基本数据类型进行修改,不会影响obj1 中复制过去的数据,而对obj2中的引用数据类型进行修改,obj1 中复制过去的引用数据类型的数据也会发生改变
$.extend(obj1,obj2);
obj2.data.time = 111;
obj2.name2 = ‘ABC’;
console.log(obj1);
console.log(obj2);
深拷贝:将对象obj2中的数据复制给obj1,对obj2中的引用数据类型进行修改,obj1 中复制过去的引用数据类型的数据不会发生改变
$.extend(true,obj1,obj2);
obj2.data.time = 456;
console.log(obj1);
console.log(obj2);