一、拷贝背景
JS引用数据类型有两类:基本数据类型和引用数据类型;
基本类型:String,Number,Boolean,Null,Undefined,symbol
这6种基本数据类型它们是直接按值存放的,所以可以直接访问。
引用类型:Function,Array,Object
,当我们需要访问这三种引用类型的值时,首先得从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。
// 代码示例:
let obj2 = Obj1; // 此处引用类型直接赋值,obj2的指向堆的地址未改变
obj2.name = "爸爸" // 看似修改的obj2,其实修改的是obj1的属性值
// obj2、obj1的 name值都被修改了。
console.log(obj1.name); // "爸爸"
console.log(obj2.name); // "爸爸"
为了解决这个问题,所以需要拷贝数据!!!!
二、浅拷贝*3
1、for in 循环拷贝
let newObj = {};
for(let key in oldObj){newObj[key] = oldObj[key];
}
console.log("拷贝对象",newObj);
2、Object.assign();对象合并拷贝
let newObj = Object.assign({},oldObj);
3、解构拷贝(…)
let newObj = { ...oldObj }
三、深拷贝*2
1、JSON拷贝
JSON.parse(JSON.stringify(Obj));
2、递归拷贝
function deepClone(Obj){let newObj = {};for(let key in Obj){newObj[key] = Obj[key];if(newObj[key] instanceof Object){deepClone(newObj[key]);}}return newObj;
}
四、浅、深拷贝区别
浅拷贝只拷贝到数据的第一层,深拷贝拷贝的数整个数据。
扩展:for in 与 for of循环
for key in 主要用于循环对象,不能循环数组
for value of 主要用于循环数组
const person = {name: 'Alice',age: 30
};
for (let key in person) {console.log(key); // 输出: name, ageconsole.log(person[key]); // 输出: Alice, 30
}
const arr = [1, 2, 3];
for (let value of arr) {console.log(value); // 输出: 1, 2, 3
}