JavaScript深拷贝与浅拷贝原理及实现方式详解
本文深入解析JavaScript中数据在堆栈内存中的存储机制,阐明深拷贝与浅拷贝的本质区别。通过遍历赋值、Object.create()以及JSON序列化三种方式,详细演示如何实现对象的浅拷贝与深拷贝,并分析各方法的适用场景与局限性,帮助开发者正确选择对象复制策略。
一、JS中数据的存储形式-堆栈
首先简要了解堆与栈的概念:
栈(Stack):计算机为原始类型数据分配的一块内存空间,用于存储 string、number 等基本类型。
堆(Heap):计算机为引用类型数据分配的一块内存空间,用于存储 object 等复杂类型。
接下来分别分析以下两段代码的执行结果:
var a = 'jack'
var b = a
b = 'andy'
console.log(a,b);//jack andyvar c = {key : 1}
var d = c
d.key = 2
console.log(c,d);//{ key: 2 } { key: 2 }阅读后可能会产生一个疑问:第一段代码逻辑清晰,但在第二段代码中,明明修改的是 d 对象的 key,为什么 c 对象中的 key 也随之改变了?
这源于堆与栈的工作原理。定义原始类型数据时,系统会开辟栈空间;声明基本变量时,其值直接存储在栈内存中。复制基本变量时,系统会将栈中的数据完整复制一份到新内存地址,因此两个变量相互独立,互不影响。若对引用类型进行复制,系统仅复制了内存地址引用,原变量与新变量指向同一堆内存地址。因此,修改新变量的属性会直接反映在原变量上。
二、深浅拷贝的三种方式
- 遍历赋值
- Object.create()
- JSON.parse()和JSON.stringify()
深拷贝与浅拷贝的核心区别在于:
假设将对象 A 赋值给对象 B,当修改 A 时,若 B 随之变化,则为浅拷贝;若 B 保持不变,则为深拷贝。
遍历赋值
参考以下代码示例:
var obj = {
a:'hello',
b:{
a:'world',
b:111
},
c:[11,'jack','abdy']
}
function clone(obj) {
var objnew = {}
for(var i in obj) {
objnew[i] = obj[i]
}
return objnew
}
var objcopy = clone(obj)
console.log(obj);
console.log(objcopy);此处定义了一个对象 obj,并编写 clone 方法以实现对象复制。调用该方法后,分别输出原对象与复制后的对象,观察其差异:

控制台输出的两个结果看似完全一致,但它们是否真正相同?
二者存在本质区别。根据浅拷贝定义,若修改 objcopy 导致 obj 发生变化,则确认为浅拷贝。
接下来进行验证,修改 objcopy.b.a 的值,观察 obj 是否随之改变:

将 objcopy.b.a 赋值为字符串 'hhhh' 后,obj.b.a 也变为 'hhhh'。这证实了初始拷贝为浅拷贝。由于 obj.b 是引用类型,objcopy.b 与 obj.b 指向同一内存地址,因此修改 objcopy.b.a 会同步影响 obj.b.a。
Object.create()
该方法仅需一行代码:
var objcopy = Object.create(obj)使用 Object.create() 复制时,原对象会被复制到新对象的原型链(__proto__)上,而非直接复制到当前对象自身属性中。再次修改 objcopy.b.a 的值,观察 obj 是否发生变化:

因此,这也属于浅拷贝。
遍历赋值实现深拷贝
以下是实现深拷贝的克隆函数:
function deepclone(startobj,endobj) {
var obj = endobj || {}
for(var i in startobj)
{
if(typeof startobj[i] === 'object') {
obj[i] = startobj[i].constructor === Array ? [] : {}
deepclone(startobj[i],obj[i])
}else {
obj[i] = startobj[i]
}
}
return obj
}需注意,在递归调用时,必须将当前处理的 obj[i] 作为参数传入,否则每次递归时 obj 会被重置为空对象,从而影响已克隆的数据结构。
接下来验证该深拷贝是否生效:
var objcopy = deepclone(obj)
objcopy.b.a = 'hhhh'
console.log(obj);
console.log(objcopy);运行结果如下:

结果表明深拷贝已成功实现。
通过JSON.parse()和JSON.stringify()实现深拷贝
这是开发工作中最常见的实现方式之一。
var objcopy = JSON.parse(JSON.stringify(obj))首先通过 JSON.stringify 将初始对象转换为字符串,再通过 JSON.parse 将其转回对象类型。
这种方式能实现深拷贝的原因在于:JSON.stringify 将对象转换为字符串后,数据存储于栈内存中,从而避免了地址引用的混淆;随后通过 JSON.parse 重新构建对象类型,实现深层复制。
至此,关于JavaScript深拷贝与浅拷贝原理的深入探究介绍完毕。如需了解更多JS深拷贝与浅拷贝相关内容,请查阅本站过往文章或继续浏览后续内容,感谢大家的支持!
D3.js 比例尺与坐标轴的配置详解
2026-11-05 16:54:46
JavaScript怎么遍历对象的Symbol键和不可枚举属性
2026-11-05 13:13:39
封装一个健壮的JS字符串判空工具函数
2026-11-05 12:16:14
JavaScript合并数组的三种常用方法:concat、扩展运算符与push
2026-11-05 11:22:29
JavaScript立即执行函数(IIFE)是什么及基本语法
2026-11-05 10:51:19
