前端面试高频考点之——深拷贝和浅拷贝

引言

在前端开发中,经常会遇到需要复制对象或数组的情况。这时候就会用到深拷贝和浅拷贝的概念。深拷贝和浅拷贝是前端面试中的高频考点,理解它们的区别和应用场景对于面试以及日常开发都非常重要。本文将详细介绍深拷贝和浅拷贝的概念、区别以及常见的实现方式。

正文

通常我们在聊到深拷贝的浅拷贝的时候,聊得一般都是引用类型的值,比如对象和数组,而原始类型的值我们一般是不聊的,因为原始类型的值无一例外都是深拷贝。

浅拷贝

大家都知道,引用类型的值都是存在堆中而不是栈中。浅拷贝是指在复制对象或数组时,只复制一层对象的引用而不是实际的对象本身。也就是说,新对象与原对象共享同一个内存地址,其中一个对象的修改会影响到另一个对象。

js 复制代码
let a = {
    age:18
 }
 let b = a
//  b的age会随着a的age的改变而改变,这就叫浅拷贝
 a.age=20
 console.log(b.age);//20

实际上常见的拷贝方法几乎都是浅拷贝,对象身上的赋值运算,Object.assign(),Object.created(),数组的解构,concat,slice以及arr.toReversed().reverse()等都是浅拷贝。那么,就不存在深拷贝的方法了吗?显然是存在的

深拷贝

什么是深拷贝? 深拷贝是指在复制对象或数组时,不仅复制对象本身,还要递归地复制对象的所有子对象,使得新对象与原对象完全独立,互不影响。目前的话就原生js中,引用类型的深拷贝就只有通过将对象转为字符串,再把字符串转为对象这一方法被广泛使用。

let obj = { name: 'Alice', age: 20 };

let newObj = JSON.parse(JSON.stringify(obj));

通常情况下,这种方法能够很好地对引用类型的值进行深拷贝,但遗憾的是,使用 JSON.stringify() 和 JSON.parse() 进行深拷贝时,会忽略 undefined、Symbol 和函数等特殊值。导致无法拷贝,并且,若尝试拷贝bigInt类型的值或者是循环引用的数据,会直接报错。

js 复制代码
let obj = {
    name: '我真的很困',
    like: {
        type: 'coding',
        a: undefined,
        b: null,
        c: function () {
            console.log('hello');
        },
        e: Symbol('hello'),
// acef都拷贝不了
    }
}
let newObj= JSON.parse(JSON.stringify(obj))
console.log(newObj);
js 复制代码
//尝试深拷贝bigInt类型
let obj={
    a:123n
}
let newObj= JSON.parse(JSON.stringify(obj))
console.log(newObj);

说到这里就不得不提一下lodash这个库了,lodash提供了cloneDeep()方法,允许我们对引用类型的值进行深拷贝,并且不会出现上面的情况。

js 复制代码
const dc = require('lodash');
let obj = { name: 'Alice', age: 20 };
let newObj = dc.cloneDeep(obj);

不过据说还有另一种方法 ,但可惜目前好像除了谷歌浏览器以外没有支持的浏览器的,属于是剑走偏锋出奇效的了。本文不做讲解,感兴趣的各位可以自行了解

深拷贝和浅拷贝的应用场景

浅拷贝适用于只需要复制一层对象引用的情况,比如克隆一个对象用于修改而不影响原始对象。

深拷贝适用于需要完全独立的对象副本的情况,比如避免修改原始对象或者将对象传递给其他函数时产生副作用。

需要根据具体的业务需求选择合适的拷贝方式,避免出现意料之外的问题。

总结

深拷贝和浅拷贝是前端开发中常见的概念,对于理解和应用它们的区别非常重要。浅拷贝只复制对象的一层引用,而深拷贝递归地复制对象及其子对象。在实际开发中,我们要根据具体的需求选择合适的拷贝方式,以确保代码的正确性和效率。

相关推荐
kyriewen8 小时前
我手写了一个 EventEmitter,面试官追问了 6 个问题——第 4 个我没答上来
前端·javascript·面试
IT_陈寒8 小时前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
小林攻城狮9 小时前
使用 Transport 节流解决 Vercel AI SDK 流式渲染卡死问题
前端·react.js
前端缘梦9 小时前
告别 TS 运行时类型漏洞!Zod 完整入门实战教程(前端 / 全栈必备)
前端·react.js·全栈
the_answer9 小时前
Webpack vs Vite 深度对比分析
前端·webpack
转转技术团队9 小时前
验证码识别实战:前端不写页面,改训模型了?
前端
MomentYY9 小时前
Temperature:AI 的“脑洞旋钮”
前端·llm·ai编程
远航_10 小时前
OpenSpec 完整详细介绍
前端·后端
召钱熏10 小时前
状态枚举正确≠渲染正确:一个语音按钮的状态机边界修复实录
android·前端
SkyWalking中文站10 小时前
认识 Horizon UI · 1/17:SkyWalking 新一代可观测性控制台
运维·前端·监控