注意:只有引用数据类型才有深拷贝和浅拷贝的概念
深拷贝和浅拷贝最根本的区别在于是否真正获取了一个对象的复制实体,而不是引用
一、浅拷贝
- 浅拷贝:仅仅是指向被复制的内存地址,如果原地址发生改变,那么浅拷贝的对象也会发生相应的改变
- 浅拷贝方式:手写浅拷贝、Object.assign()、拓展运算符...
1、手写浅拷贝:原始对象的一级属性不会被修改,但是二级以上会被修改
var obj = {
name: "张三",
age: 18,
sex: "男",
like: ["吃", "喝", "玩", "乐"]
}
function shallowCopy(obj) {
var objNew = {};
for (var key in obj) {
objNew[key] = obj[key];
}
return objNew;
}
var newObj = shallowCopy(obj);
newObj.name = "李四"; // 修改一级属性 将新对象中的张三改为李四
console.log(obj, newObj); // 原对象不变,新对象变为李四
newObj.like[1] = "hello"; // 修改二级属性 将“喝” 改为hello
console.log(obj, newObj); //愿对象与新对象中的值都发生变化
2、Object.assign()实现浅拷贝
当对象只有一层时,使用Object.assign()可以实现深拷贝
var obj = {
name: "张三",
age: 18,
sex: "男",
like: ["吃", "喝", "玩", "乐"]
}
var newObj = Object.assign({},obj);
newObj.name = "李四"; // 修改一级属性 将新对象中的张三改为李四
console.log(obj, newObj); // 原对象不变,新对象变为李四
newObj.like[1] = "hello"; // 修改二级属性 将“喝” 改为hello
console.log(obj, newObj); //愿对象与新对象中的值都发生变化
3、拓展运算符 展开运算符...实现浅拷贝
var obj = {
name: "张三",
age: 18,
sex: "男",
like: ["吃", "喝", "玩", "乐"]
}
var newObj = {...obj };
newObj.name = "李四"; // 修改一级属性 将新对象中的张三改为李四
console.log(obj, newObj); // 原对象不变,新对象变为李四
newObj.like[1] = "hello"; // 修改二级属性 将“喝” 改为hello
console.log(obj, newObj); //愿对象与新对象中的值都发生变化
二、深拷贝
- 深拷贝:在计算机中开辟了一块新的内存地址用于存放复制的对象
- 浅拷贝方式:手写深拷贝、json实现深拷贝、lodash中的 _.cloneDeep函数
1、手写深拷贝
var obj = {
a: undefined,
b: "hello",
c: 20,
d: {
age: 18,
arr: [1, 2, 3, 4]
},
e: ["hello", "world"]
}
var obj1 = deepClone(obj);
obj1.d.arr[1] = "你好";
console.log(obj, obj1); //obj1中的改变 obj中的不变 二者互不影响
// 深拷贝封装
function deepClone(obj) {
var newObj = getType(obj) == "Array" ? [] : {};
if (typeof obj !== "object") {
return obj;
} else {
for (var k in obj) {
// console.log(obj[k]);
newObj[k] = typeof(obj[k]) == "object" ? deepClone(obj[k]) : obj[k];
}
}
return newObj;
}
// 获取数据类型封装
function getType(obj) {
var type = typeof obj;
if (type !== "object") {
return type;
} else {
return Object.prototype.toString.call(obj).slice(8, -1);
}
}
2、json方法实现深拷贝
// JSON.parse(); 将json字符串转换为js对象
// JSON.stringify();将js对象转换为json字符串
var obj = {
name: "张三",
age: 18,
like: ["吃", "喝", "玩", "乐"]
}
var obj1 = JSON.parse(JSON.stringify(obj));
obj1.like[2] = "学习";
console.log(obj, obj1); // obj1改变 obj不变 二者互不影响
3、lodash中的 _.cloneDeep函数
<!-- <scriprt src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.js"> </script> -->
<script src="./lodash1.js"></script>
<script>
var obj = {
a: "hi",
b: 20,
c: {
name: "张三",
arr: [1, 2, 3]
},
d: ["hello", "world"]
}
var newObj = _.cloneDeep(obj);
newObj.c.arr[1] = "666";
console.log(obj, newObj); //newObj改变 obj未发生变化
</script>
npm i lodash 安装依赖
import _ from 'lodash' 导入依赖
var newObj = _.cloneDeep(obj); 使用深拷贝