> 技术文档 > 【js(8)js深拷贝和浅拷贝】

【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);