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

引言

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

正文

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

浅拷贝

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

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

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

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

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

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

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

总结

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

相关推荐
知识分享小能手14 分钟前
Html5学习教程,从入门到精通,HTML5 简介语法知识点及案例代码(1)
开发语言·前端·javascript·学习·前端框架·html·html5
IT、木易17 分钟前
大白话React第二章深入理解阶段
前端·javascript·react.js
晚安72022 分钟前
Ajax相关
前端·javascript·ajax
图书馆钉子户24 分钟前
怎么使用ajax实现局部刷新
前端·ajax·okhttp
bin915341 分钟前
DeepSeek 助力 Vue 开发:打造丝滑的单选按钮(Radio Button)
前端·javascript·vue.js·ecmascript·deepseek
qianmoQ44 分钟前
第五章:工程化实践 - 第五节 - Tailwind CSS 常见问题解决方案
前端·css
那就可爱多一点点1 小时前
超高清大图渲染性能优化实战:从页面卡死到流畅加载
前端·javascript·性能优化
不能只会打代码2 小时前
六十天前端强化训练之第一天HTML5语义化标签深度解析与博客搭建实战
前端·html·html5
OpenTiny社区2 小时前
Node.js技术原理分析系列——Node.js的perf_hooks模块作用和用法
前端·node.js
菲力蒲LY2 小时前
输入搜索、分组展示选项、下拉选取,全局跳转页,el-select 实现 —— 后端数据处理代码,抛砖引玉展思路
java·前端·mybatis