【js(8)js深拷贝和浅拷贝】
深拷贝和浅拷贝
- 一、引用类型的特性
- 二、浅拷贝
-
- 1.Object.assign() 实现浅拷贝
- 2. 展开运算符实现浅拷贝
- 3.使用Array.slice() 实现浅拷贝
- 4.使用Array.from() 实现浅拷贝
- 三、深拷贝
-
- 1.JSON 序列化/反序列化实现深拷贝
- 2. 手动递归实现深拷贝
- 3.使用第三方库实现深拷贝
一、引用类型的特性
js有基本类型的引用类型,区别:
- 基本类型(如 number、string、boolean):按值存储和传递,保存在栈内存中
- 引用类型(如 object、array、function):按引用存储和传递
- 引用类型数据保存在堆内存中,
- 引用数据类型的变量是一个指向堆内存中实际对象的引用,存在栈中
let original = { name: \"Alice\", info: { age: 25 } }; // 浅拷贝 let shallowCopy = Object.assign({}, original); shallowCopy.info.age = 30; console.log(original.info.age); // 输出 30,因为 info 对象是共享的 // 深拷贝 let deepCopy = JSON.parse(JSON.stringify(original)); deepCopy.info.age = 40; console.log(original.info.age); // 输出 25,原始对象未受影响
二、浅拷贝
- 浅拷贝创建一个新对象,但是只复制原始对象第一层属性的值
- 如果属性是基本类型,则复制其值
- 如果属性是引用类型,则复制其引用(地址)
1.Object.assign() 实现浅拷贝
const original = { name: \"John\", details: { age: 30 } };const shallowCopy = Object.assign({}, original);shallowCopy.name = \"Jane\"; // 不影响原对象shallowCopy.details.age = 25; // 影响原对象!console.log(original.name); // 输出: \"John\"console.log(original.details.age); // 输出: 25
2. 展开运算符实现浅拷贝
const original = { name: \"John\", details: { age: 30 } };const shallowCopy = { ...original };// 行为与 Object.assign() 相同
3.使用Array.slice() 实现浅拷贝
const originalArray = [1, 2, { value: 3 }];const slicedArray = originalArray.slice();
4.使用Array.from() 实现浅拷贝
const fromArray = Array.from(originalArray);
三、深拷贝
- 深拷贝开辟一个新的栈,两个对象属性完全相同,但是对应两个不同的地址,
- 修改一个对象的属性,不会改变另一个对象的属性
1.JSON 序列化/反序列化实现深拷贝
- 简单但是有限制的方法
- 不能复制函数、undefined、Symbol、BigInt
- 不支持循环引用的对象
let obj = { a: 1, b: { c: 2 } };let deepCopy = JSON.parse(JSON.stringify(obj));
2. 手动递归实现深拷贝
- 手动递归复制对象及其属性
- 直到所有属性都是基本数据类型为止
function deepClone(obj) {//基本类型直接返回 if (typeof obj !== \'object\' || obj === null) { return obj; } const newObj = Array.isArray(obj) ? [] : {}; for (let key in obj) { if (obj.hasOwnProperty(key)) { newObj[key] = deepClone(obj[key]); } } return newObj;}const originalObj = { name: \'John\', age: 30, address: { city: \'Beijing\', country: \'China\' } };const newObj = deepClone(originalObj);newObj.address.city = \'Guangzhou\';console.log(\'originalObj:\',originalObj); console.log(\'newObj:\',newObj);
3.使用第三方库实现深拷贝
- 如Loadsh、jQuery等
- 会增加项目的依赖和代码体积
const originalObj = { name: \'John\', age: 30, address: { city: \'Beijing\', country: \'China\' } };const newObj = _.cloneDeep(originalObj);newObj.address.city = \'Guangzhou\';console.log(newObj);