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

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

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

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

总结

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

相关推荐
码界奇点16 分钟前
Java Web学习 第15篇jQuery从入门到精通的万字深度解析
java·前端·学习·jquery
小鑫同学1 小时前
Alias Assistant:新一代 macOS Shell 别名管理解决方案
前端·前端工程化
꒰ঌ小武໒꒱1 小时前
RuoYi-Vue 前端环境搭建与部署完整教程
前端·javascript·vue.js·nginx
名字越长技术越强1 小时前
前端之相对路径
前端
望道同学2 小时前
PMP/信息系统项目管理师 9 张 思维导图【考试必备】
前端·后端·程序员
局i2 小时前
Vue 中 v-text 与 v-html 的区别:文本渲染与 HTML 解析的抉择
前端·javascript·vue.js
fruge3 小时前
接口 Mock 工具对比:Mock.js、Easy Mock、Apifox 的使用场景与配置
开发语言·javascript·ecmascript
菜鸟冲锋号3 小时前
问题:增量关联(实时同步新数据) 这个场景中,如果hudi_pay 变更了一条数据,hudi_order_pay_join 结果的数据会跟着变化吗
服务器·前端·数据库
贩卖黄昏的熊3 小时前
typescript 快速入门
开发语言·前端·javascript·typescript·ecmascript·es6
拾柒SHY3 小时前
XSS-Labs靶场通关
前端·web安全·xss