先介绍一下JavaScript中的深浅拷贝
- 在复制引用数据类型(主要是对象和数组)时:
- 浅拷贝: 复制存储地址 相互有关联 ---相互受影响
- 深拷贝:复制具体数值 相互没有关联 ---相互不受影响
- 浅拷贝
- 代码展示
// 定义引用数据类型
const obj1 = {
name: 'jack',
age: 18,
sex: '男',
addr: '北京',
};
// 执行浅拷贝
// 直接将引用数据类型的地址,赋值给另一个变量
// 实际上是将obj1的地址,赋值给obj2存储
// 此时 obj2和obj1 存储的是相同的内存地址
// 就相当于 obj2 和 obj1 操作的是相同的内存地址
const obj2 = obj1;
// 通过obj2 ,修改 存储的数据单元
obj2.name = 'marry';
// 查看存储的内容,obj1和obj2都是修改之后的内容
console.log(obj2);
console.log(obj1);
- 结果展示

-
说明
浅拷贝复制的是存储地址,相当于一个银行账户,通过存折、银行卡、手机都可以操作,任何一个操作都会影响金额数值。
- 深拷贝
-
代码展示
// 定义引用数据类型 const obj3 = { name : 'jack', age : 18, sex : '男', addr : '北京', }; const obj4 = {}; for(let key in obj3){ // 将 obj3 的键名,作为obj4的键名 // 将 obj3 的数值,作为obj4的数值 // 也就是将 obj3的键名数值,复制拷贝给 obj4 obj4[key] = obj3[key]; } obj4.name = 'mary'; console.log(obj3); console.log(obj4); -
结果展示

-
说明
深拷贝复制的是数据内容,obj3和obj4是两个独立的引用数据类型;任意一个变量,修改存储的数值,对另一个变量,不影响
- 总结:
- 实际项目中:深浅拷贝都会用到,具体要看项目需求
- 有待解决的问题:
-
如果单元中存储的是多维数组或者对象数据,只是简单的循环遍历无法解决
使用原生js,是写一个递归函数,判断数据类型如果是数组或对象 :调用函数本身,再次执行一个深拷贝 (现在基本不用了,都用jQuery)
-
再来介绍jQuery中深浅拷贝的使用方法:
-
语法 $.extend(参数1,参数2,参数3,参数4,参数5.....)
参数1:是否深拷贝,默认值false(表示默认是浅拷贝),也可以不写 参数2: 将参数2之后的内容都拷贝到参数中如果存储的是基本数据类型,拷贝之后两个变量之间的操作,相互不会影响
-
代码展示
// 定义引用数据类型
const obj = {
id : 1,
userName : 'jack',
userPwd : '123456',
phone : '12345678901',
data : {
sex : '男',
age : 18,
},
};
const newObj = {};
// 默认值是false,或者不写
// 默认执行的是浅拷贝
// 如果存储的是基本数据类型,拷贝之后,两个变量之间的操作,相互不会影响
// 如果存储的是引用数据类型,拷贝之后,两个变量之间的操作,相互会影响
$.extend(newObj , obj);
// 如果设定参数1为 true
// 执行的是深拷贝
// 如果存储的是引用数据类型,拷贝之后,两个变量之间的操作,相互不会影响
$.extend(true , newObj , obj);
// 修改id存储的数据,存储的是基本数据类型,相互不会影响
obj.id = 100;
// 修改data存储的数据,存储的是引用数据类型,相互会影响
obj.data.sex = '女';
console.log(newObj);
console.log(obj);
- 特别说明
-
jQuery中的$.extend 指的是:针对于二维甚至多维的设定。 默认第一位执行的都是深拷贝,而且不能设定、不能修改 。
-
参数1的true/默认的false 针对的是:二维或者三、四维深浅拷贝的设定。 如果要想直接浅拷贝,newObj = obj做赋值就可以,没必要用$.extend()