当面试官让你谈谈深浅拷贝,你怎么说?

前言

上一篇文章给大家介绍了一些js方面的考题,相信应该对大家应该有所帮助。深浅拷贝也是js中常考的一道题,常见的回答相信大家都见过了,那么这篇文章就带你看看进阶版的回答。
前端面试必考八股文之------js系列(1)

是什么?

  • 浅拷贝
    只拷贝一层对象,复制这一层对象中原始类型的属性值,如果有引用类型的话,就复制它的指针(引用地址)
  • 深拷贝
    层层拷贝,所有类型的属性值都会被复制,原对象的修改不会影响拷贝后的对象
  • 深浅拷贝通常只针对引用类型:
    原始类型拷贝后修改原属性值不会对拷贝后的值产生影响,所以讨论原始类型的深浅拷贝没有意义,或者说原始类型都是深拷贝

如何实现深浅拷贝的效果?

  • 浅拷贝
    Object.assign concat slice [...arr]
    这里很多人会有疑惑,concatslice不是数组上面的方法吗?但是大家可能忽略了一个问题,数组也是引用类型,深浅拷贝针对的是所有的引用类型,所以数组也算在内。
js 复制代码
let obj = {
    a: 1,
    b: 2
}
let newObj = Object.assign({}, obj)

let arr = [1,2,3]
let newArr = [].concat(arr)
arr.push(4)
console.log(newArr);    // [1,2,3],不影响新数组

// 但是如果这样写就会影响
let arr2 = [1,2,3,{n: 4}]
let newArr2 = [].concat(arr2)
arr2[3].n = 5
console.log(newArr2);   // [1,2,3,{n: 5}]

let newArr = arr.slice(0,arr.length)
let newArr = [...arr]

其实还有一个方法,也能实现浅拷贝效果,就是Object.create(obj),但是它一般不放在浅拷贝的范畴里。

js 复制代码
let obj = {
    a: 1,
    b: 2
}
let newObj2 = Object.create(obj)
console.log(newObj2);   // {}
console.log(newObj2.a);   // 1

因为Object.create(obj)创建了一个新的空对象newObj2,让newObj2隐式继承了obj的属性,即执行了一个这样的操作newObj2.__proto__ = obj,深浅拷贝一般指的是拷贝对象上的显式具有的属性,所以Object.create(obj)就没被算在内,但是你把这个告诉面试官,同样会让他对你眼前一亮。

  • 深拷贝
    实现深拷贝就这一个方法JSON.parse(JSON.stringify(obj)),但是它有一个缺陷就是不能拷贝undefinedSymbolfunction,它的原理很简单,就是把对象先转为字符串,然后再转为对象,这样拷贝前后的两个对象就是两个单独的个体,有两个不同的引用地址,就不会相互影响。

如何实现深浅拷贝?

注意审题哦,这里说的是如何实现深浅拷贝?,而不是如何实现深浅拷贝的效果?,它的意思是让你手动实现深浅拷贝,要你手撕代码。

  • 浅拷贝
    这里就有一点要注意一下,拷贝是拷贝对象显式具有的属性,所以在拷贝前要先判断该属性是不是对象显式具有的
js 复制代码
function shallowCopy(obj) {
    let newObj = {}
    for (let key in obj) {
        // 判断该属性是否是原对象显式具有的属性
        if (obj.hasOwnProperty(key)) {
            newObj[key] = obj[key]
        }        
    }
    return newObj
}
  • 深拷贝:
    实现深拷贝常见的就是递归,相信很多人都会选择用这个方法。
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
}

这里再给大家介绍一个进阶版的方法structuredClone(obj),这是es6新增的专门用来实现深拷贝的方法,但它一样有个缺陷,就是不能拷贝Symbolfunction

但是相较于JSON.parse(JSON.stringify(obj))来说,它能够拷贝undefined

js 复制代码
let obj = {
    a: 1,
    b: {
        n: 2
    },
    c: undefined
}
const obj2 = structuredClone(obj)
console.log(obj2);   // { a: 1, b: { n: 2 }, c: undefined }

结语

js中的深浅拷贝是面试里常考的题目之一,虽然也比较简单,但是给大家介绍了一些进阶版的回答是不是更能提高面试官对你的好感度呢?

相关推荐
前端大卫23 分钟前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友25 分钟前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理2 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻2 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
mapbar_front3 小时前
在职场生存中如何做个不好惹的人
前端
牧杉-惊蛰3 小时前
纯flex布局来写瀑布流
前端·javascript·css
一袋米扛几楼984 小时前
【软件安全】什么是XSS(Cross-Site Scripting,跨站脚本)?
前端·安全·xss
向上的车轮4 小时前
Actix Web适合什么类型的Web应用?可以部署 Java 或 .NET 的应用程序?
java·前端·rust·.net
XiaoYu20025 小时前
第1章 核心竞争力和职业规划
前端·面试·程序员
excel5 小时前
🧩 深入浅出讲解:analyzeScriptBindings —— Vue 如何分析 <script> 里的变量绑定
前端