Skip to Content

面试导航 - 程序员面试题库大全 | 前端后端面试真题 | 面试

Javascript浅拷贝和深拷贝

浅拷贝和深拷贝是复制对象时常用的两种方式。它们的主要区别在于,拷贝对象的层级结构和引用关系。

好的,让我再详细解释一下浅拷贝和深拷贝的区别,并列举所有常见的 深拷贝方法。

浅拷贝(Shallow Copy)

浅拷贝指的是创建一个新对象,但该对象仅复制原对象的第一层属性,如果属性是基本数据类型(如字符串、数字等),会复制其值;如果属性是引用类型(如数组、对象等),则复制的是引用,两个对象中的引用类型属性指向同一个内存地址。

浅拷贝的关键点在于,它只会复制对象的顶层内容,对于深层次的引用类型属性,还是共享同一个地址。

如下代码所示:

const obj1 = { a: 1, b: [2, 3] }; const obj2 = Object.assign({}, obj1); // 浅拷贝 // 修改 obj2 中的数组 obj2.b.push(4); console.log(obj1.b); // [2, 3, 4],obj1 也被修改了 console.log(obj2.b); // [2, 3, 4]

最终输出结果如下图所示:

浅拷贝方法如 Object.assign() 和展开运算符(...)只复制对象的第一层,对于引用类型的属性,会复制引用而非实际数据,因此修改新对象中的引用类型属性可能会影响原对象。需要注意的是,for...in 用于遍历对象的属性名,而非属性值。

深拷贝(Deep Copy)

深拷贝指的是递归地复制对象及其所有嵌套对象。它会创建新对象,并确保新对象与原对象完全独立,深拷贝不会共享任何引用类型的内存地址。

深拷贝的关键在于,所有对象的嵌套属性都会被复制一份,且引用类型的属性指向新对象的内存地址,而非原对象。

如下代码代码所示:

const obj1 = { a: 1, b: { c: 2 } }; const obj2 = JSON.parse(JSON.stringify(obj1)); // 深拷贝 obj2.b.c = 3; console.log(obj1.b.c); // 2,原对象不受影响 console.log(obj2.b.c); // 3

最终输出结果如下图所示:

JSON.parse(JSON.stringify(obj))

通过将对象转为 JSON 字符串再解析为新对象实现深拷贝,但此方法只能处理简单数据类型,无法处理 undefinedfunctionDateMapSetRegExp 等复杂类型,也无法处理循环引用。

const obj1 = { a: 1, b: [2, 3], d: new Date() }; const obj2 = JSON.parse(JSON.stringify(obj1)); obj2.b.push(4); console.log(obj1.b); // [2, 3],原对象不受影响 console.log(obj2.b); // [2, 3, 4] console.log(obj1.d instanceof Date); // true,Date 不会被复制

递归自定义深拷贝

自定义的深拷贝函数通过递归地遍历对象的每一层,逐层复制原对象的所有值,确保对象完全独立。

function deepCopy(obj) { if (obj === null || typeof obj !== 'object') return obj; // 基础数据类型直接返回 const newObj = Array.isArray(obj) ? [] : {}; // 创建新对象或数组 for (let key in obj) { if (obj.hasOwnProperty(key)) { newObj[key] = deepCopy(obj[key]); // 递归复制 } } return newObj; } const obj1 = { a: 1, b: { c: 2 } }; const obj2 = deepCopy(obj1); obj2.b.c = 3; console.log(obj1.b.c); // 2,原对象不受影响 console.log(obj2.b.c); // 3

structuredClone()

structuredClone() 是浏览器提供的原生方法,可以深拷贝大多数 JavaScript 对象,包括 DateMapSet 等,且比 JSON.parse(JSON.stringify()) 更强大,能够正确处理更多数据类型。

const obj1 = { a: 1, b: { c: 2 }, d: new Date() }; const obj2 = structuredClone(obj1); obj2.b.c = 3; console.log(obj1.b.c); // 2,原对象不受影响 console.log(obj2.b.c); // 3 console.log(obj1.d instanceof Date); // true,Date 被正确复制

如下图所示:

深拷贝 vs 浅拷贝

特性浅拷贝深拷贝
拷贝层级仅拷贝第一层对象递归拷贝所有层级的对象
引用类型处理引用类型属性仍指向原对象引用类型属性被完全拷贝,指向新对象
性能快于深拷贝相对较慢,特别是在对象嵌套较深时
适用场景适用于对象结构简单,且不涉及深层引用的情况适用于需要完全独立的副本,避免引用关系共享

总结

深拷贝适用于需要完全独立副本的情况,尤其是对象包含复杂类型或多层嵌套时。浅拷贝则适用于对象没有嵌套引用类型,或者只需复制对象的第一层属性时。

浅拷贝只复制对象的第一层,对于引用类型,复制的是内存地址,导致对象之间共享引用类型的数据;深拷贝则递归复制所有层级,确保对象完全独立,常用方法包括 JSON.parse(JSON.stringify())、递归自定义深拷贝和 structuredClone()

最后更新于:
Copyright © 2025Moment版权所有粤ICP备2025376666