请你谈谈深拷贝和浅拷贝?面试官这么问,你就这么答。

快面试了还不知道深拷贝,浅拷贝?面试官这么问,你就这么答

哈喽哈喽,我是你们的金樽清酒。马上就到金三银四的面试潮了。大家都准备好了面试的内容嘛。最近我的小伙伴就面试了一个大型公司,被面试官狠狠的折磨了一下,当然面试这个东西肯定是越面越勇的,所以掘友们也不要担心。来让我们一起回顾一下js的考点,争取让面试官刮目相看。

面试官让你谈一谈深拷贝和浅拷贝?

当碰到面试官叫你谈谈某个东西的时候。小伙伴们是不是千言万语堵在心里但是说不上来,因为这个的回答范围太广了,让我们无从下手,但是呢,其实这个问题是有模板可以套进去的,帮助我们的语言表达。

  • 首先谈是什么,我们可以谈谈什么是深拷贝和浅拷贝以及区别,深浅拷贝通常只针对引用类型。浅拷贝:只拷贝一层对象,复制这一层对象中的原始值,如果有引用类型的话,就复制它的指针。 深拷贝:层层拷贝,所有类型的属性值都会被复制,原对象的修改不会影响拷贝后的对象。这就是深拷贝和浅拷贝的区别。

  • 如何实现浅拷贝 js当中的assign,concat,slice,解构等方法都可以实现浅拷贝的效果。大家可以尝试一下。由于浅拷贝只会复制一层对象,复制这一层对象的原始值,所以如果再有一层对象只会复制引用地址,所以修改嵌套对象里面的值,拷贝对象里面的值也会发生改变。这个也涉及到js的预编译阶段。引用数据类型要额外的用堆结构来存储,而在全局执行上下文里面变量的值是这个引用地址。对象里面发生了改变,又是拷贝同一个引用地址,所以拷贝后的对象里面的值也会发生改变。

简单的描述一下 如何手写一个实现浅拷贝的函数

js 复制代码
function shallowCopy(obj) {
    let newObj = {}
    for (let key in obj) {
        if (obj.hasOwnProperty(key))
            newObj[key] = obj[key]
    }
    return newObj
}//浅拷贝方法

实现的原理是什么呢?诶,拷贝嘛,那就是复制一份。那我们肯定要遍历一遍原对象,用另一个空对象来存值。并且拷贝有一个原则就是不会复制隐式原型上面的方法,所以我们要用hasOwnProperty来判断是否为自有属性,然后赋值,return 出拷贝的新对象,这就是实现浅拷贝的方法。

让我们测试一下

js 复制代码
let obj = {
    a: 1,
    b: {
        n: 2
    }
}
let obj2 = shallowCopy(obj)

function shallowCopy(obj) {
    let newObj = {}
    for (let key in obj) {
        if (obj.hasOwnProperty(key))
            newObj[key] = obj[key]
    }
    return newObj
}//浅拷贝方法
obj.b.n = 3
console.log(obj2)

我们可以看到拷贝成功,然后自行修改b对象里面的值为3

可以看到值也修改成功,因为浅拷贝只拷贝一层对象的原始类型的值,引用类型只会复制引用地址,而引用地址一样,修改了该引用地址里面的值,所以值也会随之更改。

  • 如何实现深拷贝 目前实现深拷贝的办法有且只有一个,JSON.parse(JSON.stringify(obj))通过这个方法先将js对象转换为JOSNZ字符串,再将JSON字符串转换为js对象来实现深拷贝。深拷贝是层层拷贝,并不是拷贝引用地址,所以后面修改值不会影响拷贝的对象。

手写一个深拷贝函数

js 复制代码
function deepCopy(obj) {
    let newObj = {}
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            if (typeof obj[key] !== 'object' || obj[key] === null) {
                newObj[key] = obj[key]
            } else {
                newObj[key] = deepCopy(obj[key])
            }
        }
    }
    return newObj

最简单的原理就是递归,我们说浅拷贝只能拷贝一层对象,那么我们就无限调用,用递归的方法,直到不是对象,将所有的内容都拷贝掉。但是还是一个原则,只复制自有属性,不复制隐式原型上的属性。所以要用hasOwnProperty方法判断是不是自有属性。然后判断类型,是对象递归,不是对象直接复制,return newObj。

测试一下

js 复制代码
let obj = {
    a: 1,
    b: {
        n: 2
    }
}
let obj2 = deepCopy(obj)
function deepCopy(obj) {
    let newObj = {}
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            if (typeof obj[key] !== 'object' || obj[key] === null) {
                newObj[key] = obj[key]
            } else {
                newObj[key] = deepCopy(obj[key])
            }
        }
    }
    return newObj
}//深拷贝的方法
console.log(obj2)

我们可以看到拷贝成功,并且将n的值修改,拷贝后的也不会发生改变。

js 复制代码
let obj = {
    a: 1,
    b: {
        n: 2
    }
}
let obj2 = deepCopy(obj)
function deepCopy(obj) {
    let newObj = {}
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            if (typeof obj[key] !== 'object' || obj[key] === null) {
                newObj[key] = obj[key]
            } else {
                newObj[key] = deepCopy(obj[key])
            }
        }
    }
    return newObj
}//深拷贝的方法
console.log(obj2)
obj.b.n=4

可以看到拷贝对象依旧不会发生变化,一个深拷贝就成功了。

总结

好了,面试官让我们谈一谈的拷贝也完成了,我们顺利的达到了关于拷贝的每一个点。首先说明白什么是拷贝,深拷贝和浅拷贝的区别。如何实现深拷贝浅拷贝。如何手写一个深拷贝和浅拷贝出来。

相关推荐
三十而立洋1 分钟前
从 0 到 1:我用 VS Code API + Git 命令写了一个"代码统计"插件
javascript
计算机魔术师2 分钟前
为了考试作弊,AI 模型黑进了 Hugging Face——这已经不是科幻了
前端
天云数据7 分钟前
从“LLM+工具”到Harness 工程:Lilian Weng新文的技术拆解,与一个生产级参考实现
java·前端·网络
三84413 分钟前
WordPress SQL 注入漏洞分析:从 author__not_in 参数到 REST API 全链路
linux·前端·数据库
IT_陈寒14 分钟前
Vite打包时踩了个坑,static资源去哪了?
前端·人工智能·后端
龙虾PRO15 分钟前
2026 年 AI 智能体工具调用:ReAct 模式与函数调用怎么选才不踩坑
前端·人工智能·react.js
何以解忧,唯有..16 分钟前
Django 框架入门指南:从零开始构建 Web 应用
前端·python·django
daols8820 分钟前
vue 甘特图 vxe-gantt 紧前紧后依赖关系连接线配置详解
前端·vue.js·甘特图
恋猫de小郭22 分钟前
Flutter iOS 的深度优化 PR,搞笑的是贡献者被 Gemini 评审折磨
android·前端·flutter
必须会一定会25 分钟前
Agent Handoff M5 发布验收:`CHANGES.md`、`npm pack`、`release:check` 与干净环境安装验证
前端·人工智能·npm·node.js·ai编程