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

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

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

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

总结

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

相关推荐
小白学习日记38 分钟前
【复习】HTML常用标签<table>
前端·html
john_hjy42 分钟前
11. 异步编程
运维·服务器·javascript
风清扬_jd1 小时前
Chromium 中JavaScript Fetch API接口c++代码实现(二)
javascript·c++·chrome
丁总学Java1 小时前
微信小程序-npm支持-如何使用npm包
前端·微信小程序·npm·node.js
yanlele1 小时前
前瞻 - 盘点 ES2025 已经定稿的语法规范
前端·javascript·代码规范
It'sMyGo1 小时前
Javascript数组研究09_Array.prototype[Symbol.unscopables]
开发语言·javascript·原型模式
懒羊羊大王呀2 小时前
CSS——属性值计算
前端·css
睡觉然后上课2 小时前
c基础面试题
c语言·开发语言·c++·面试
xgq2 小时前
使用File System Access API 直接读写本地文件
前端·javascript·面试
李是啥也不会2 小时前
数组的概念
javascript