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

引言

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

正文

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

浅拷贝

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

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

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

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

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

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

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

总结

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

相关推荐
Y42581 小时前
本地多语言切换具体操作代码
前端·javascript·vue.js
速易达网络4 小时前
Bootstrap 5 响应式网站首页模板
前端·bootstrap·html
etsuyou4 小时前
js前端this指向规则
开发语言·前端·javascript
lichong9514 小时前
Android studio 修改包名
android·java·前端·ide·android studio·大前端·大前端++
cai_huaer4 小时前
BugKu Web渗透之 cookiesWEB
前端·web安全
lichong9514 小时前
Git 检出到HEAD 再修改提交commit 会消失解决方案
java·前端·git·python·github·大前端·大前端++
友友马5 小时前
『 QT 』QT控件属性全解析 (一)
开发语言·前端·qt
不想上班只想要钱5 小时前
vue3+vite创建的项目,运行后没有 Network地址
前端·javascript·vue.js
流***陌6 小时前
手办盲盒抽赏小程序前端功能设计:兼顾收藏需求与抽赏乐趣
前端·小程序
岁月宁静6 小时前
在富文本编辑器中封装实用的 AI 写作助手功能
前端·vue.js·人工智能