浅拷贝
缺点 : 只会拷贝栈内存中的对象内存地址, 两个对象 仍然使用的是一个内存地址,如果修改对象中的属性,那么另一个对象也会被影响(因为内存地址指向同一个堆内存)
let a = { name: "我是a" }
/* a的内存地址 指向栈内存中的内容, */
// 浅拷贝 拷贝的只是栈内存中 a 的内存地址
// 如果修改B内存地址中的内容 A也会被修改 因为他俩指向的都是同一个堆内存)
let b = a
console.log(b); // {name:"我是a"}
b.name = "我是b" //这里修改了b的name属性(内存地址 指向的 堆内存 内容改变)
console.log(b); //{name:"我是b"}
console.log(a); //{name:"我是b"} //因为内存地址中的 堆内存内容被改变了
深拷贝
(引用数据类型)普通数据类型 不存在深拷贝与浅拷贝
方法一: 拷贝对象 ,只拷贝一层, 下面终极方案 可以真正完成 深拷贝(对象 和 数组)
思想 封装一个方法 将要深拷贝的对象传递进去 , 然后for in 遍历 ,方法返回一个新的对象(拷贝以后的对象)
// 深拷贝 定义一个方法
function copyObj(obj) {
let result = {}
for (let key in obj) {
result[key] = obj[key]
}
return result
}
let a = { name: "我是a", age: "awdaw" }
let b = copyObj(a)
//深拷贝以后 因为使用的不是使用的一个内存地址
// 所以b修改堆内存中的值 a 堆内存中的值不会被影响
b.name = "我是b"
console.log(b); //{ name:"我是b", age:"awdaw"}
console.log(a); //{ name: "我是a", age: "awdaw"}
方法二: 拷贝对数组
// 深拷贝 定义一个方法
function copyObj(obj) {
let result = {}
for (let key in obj) {
result[key] = obj[key]
}
return result
}
let a = [1, 2, 3, 4, 5, 6, 7, 8]
let b = copyObj(a) //深拷贝以后 因为使用的不是使用的一个内存地址
// 所以b修改堆内存中的值 a 堆内存中的值不会被影响
b[0] = "修改了"
console.log(b); //["修改了", 2, 3, 4, 5, 6, 7, 8]
console.log(a); //[1, 2, 3, 4, 5, 6, 7, 8]
终极方案: 深拷贝 对象 + 数组 无论值是否为复杂类型 都会被深拷贝
// 终极方案 根据传入的 类型 进行判断 function copyObj(obj) {
// 判断传入的是什么类型, 根据类型 返回一样类型的返回值
let result;
if (Object.prototype.toString.call(obj) == "[object Array]") {
result = []
} else if (Object.prototype.toString.call(obj) == "[object Object]") {
result = {}
} else {
return "请输入正确的复杂数据类型"
}
for (let key in obj) {
//使用递归!!!!! 判断值中 是否存在复杂类型 如果存在复杂类型,那么 使用递归 对值在进行一次深拷贝,无论多少层都不会被影响
if (typeof obj[key] == "object") {
result[key] = copyObj(obj[key]) //此时这里的值为 {name:122} 深拷贝了,修改不会被影响
// 跳出本次循环 进入下一次,下面代码不再执行
break
}
result[key] = obj[key]
}
// 将深拷贝以后的结果 返回
return result
}
let obj = {
name: 111, two: {
name: 122, age: {
w: 1111
}
}
}
//进行深拷贝 这里是对象
let newObj = copyObj(obj)
newObj.two.age.w = "我也被修改楼"
newObj.two.name = "我修改了"
console.log(newObj);
console.log(obj);
//修改以后的结果 不会影响 被拷贝的对象
//进行深拷贝 这里是数组
let arr = [1, 2, 3, 4, 5, 6, ["第二层", { name: "第二层中的复杂类型" }]]
let newArr = copyObj(arr)
// 修改newArr的内容 arr 不会被影响
newArr[6][0] = "我也修改了" //不会影响 arr
newArr[6][1].name = "修改了" //不会影响 arr
console.log(newArr);
console.log(arr);
//修改以后的结果 不会影响 被拷贝的数组