「通俗读物」- 深拷贝和浅拷贝

前言

大家好,我是珂圩

  深浅拷贝在工作中也经常使用,大家多多少少都有些了解

  本章来总结记录一下深浅拷贝的区别和方法,希望对你有所帮助

数据类型的存储方式

首先我们需要了解数据类型

  • 基本类型: number,string...
  • 引用类型: object

每种类型是如何存储的

基本类型 :保存在栈内存

引用类型 :保存在堆内存中,然后在栈内存中保存该数据堆内存的索引

浅拷贝

  浅拷贝就是指只拷贝了栈内存中的数据 ,也就是说这份数据中存在引用类型的数据,也只是拷贝了该数据在栈内存中的索引

  假如我们浅拷贝一份数据后(数据中含有引用类型),再修改拷贝后的数据中的引用类型,此时远数据也会改变

总结一下

  • 如果是基本类型就是拷贝基本类型的值
  • 如果是引用类型则是拷贝的内存地址

实现一个浅拷贝

js 复制代码
    function shallowClone(obj){
        const newObj = {}
        for(let prop in obj){
            if(obj.hasOwnProperty(prop)){
                newObj[porp] = obj[prop]
            }
        }
        return newObj
    }

在JavaScript中存在浅拷贝的方法有

object.assign

js 复制代码
    const obj = {...}
    const newObj = Object.assign({},obj)

Array.prototype.slice()

js 复制代码
    const arr = [1,2,3]
    const newArr = arr.slice(0) 

Array.prototype.concat()

js 复制代码
    const arr = [1,2,3]
    const newArr = arr.concat(0) 

...(扩展运算符)

js 复制代码
    const arr = [1,2,3]
    const newArr = [...arr]

深拷贝

  深拷贝就是将数据完全拷贝成一个新数据,也就是开了一块新内存在存储数据, 修改拷贝后的新数据老数据也不会变

  使用JSON.stringify()实现简易版的深拷贝,但是其中会存在一些问题,这种方式会忽略 undefined、symbol、function(函数)

js 复制代码
const obj = {...}
const newObj = JSON.parse(JSON.stringify(obj))

还有一种方式是循环递归来实现深拷贝

js 复制代码
function cloneDeep (obj,hash = new weakMap()){
    if(obj == null) return obj
    if(obj instanceof Date) return new Date(obj)
    if(obj instanceof RegExp) return new RegExp(obj)
    if(typeof obj !== 'object') return obj
    if(hash.get(obj)) return hash.get(obj)
    let cloneObj = new obj.constructor()
    hash.set(obj,cloneObj)
    for(let key in obj){
        if(obj.hasOwnProperty(key)){
            cloneObj[key] = cloneDeep(obj[key],hash)
        }
    }
    return cloneObj
}

结语

如果此文章对你有帮助,点个赞支持一下

后续还会不定时出一些文章或针对某个领域的系列文章

有兴趣的可以关注一下!

相关推荐
天才熊猫君21 分钟前
配置与数据分离:一种可视化搭建的属性编辑方案
前端·javascript
林希_Rachel_傻希希31 分钟前
web性能之相关路径——AI总结
前端·javascript·面试
竹林81839 分钟前
用 wagmi v2 踩坑两天,我终于搞懂了多链钱包切换在 DeFi 前端中的正确姿势
前端·javascript
用户21366100357242 分钟前
Vue项目搜索功能与面包屑导航
前端·javascript
星栈1 小时前
LiveView 的实时通信,爽是爽,但 PubSub 和广播也最容易把自己绕晕
前端·前端框架·elixir
用户2930750976691 小时前
告别关键词匹配,拥抱向量语义 —— RAG 搜索从零到一
前端
独孤留白1 小时前
从C到Rust:告别 C 的"指针 + 长度"手动模式
前端·rust
掘金安东尼2 小时前
中小厂前端候选人简历面试拆解:从 HR 面、技术面到主管面的双赢提问法
前端·面试
天平10 小时前
油猴脚本创建webworker踩坑记录
前端·javascript·typescript