你所不知道的 JavaScript 深浅拷贝

直接赋值 (引用)、浅拷贝、深拷贝

区别

  • 直接赋值 (引用): 其实就是对象的引用(别名)
  • 浅拷贝: 拷贝父对象,不会拷贝对象的内部的子对象
  • 深拷贝: 完全拷贝了父对象及其子对象

解析

  1. b = a: 赋值引用,a 和 b 都指向同一个对象
  1. b = a.copy(): 浅拷贝, a 和 b 是一个独立的对象,但他们的子对象还是指向统一对象(是引用)
  1. b = copy.deepcopy(a): 深度拷贝, a 和 b 完全拷贝了父对象及其子对象,两者是完全独立的

实现

浅拷贝

  1. 对象:Object.assign()
javascript 复制代码
var obj = {a:{a:"kobe",b:39}}
var initalObj = Object.assign({},obj)
initalObj.a.a = "wade"
console.log(obj.a.a) //wade

这个 API 还可用于 对象合并

javascript 复制代码
const ul = {name:"zhangsan"}
const u2 = {age: 12}
const u3 = Object.assign(ul,u2);
console.log(u3) // { name:'zhangsan',age: 12 }

object 只有一层的时候,是 深拷贝

  1. 数组:concat、slice
javascript 复制代码
let arr1 = [ 1, 3, {
    username:'kobe'
}]

let arr2 = arr1.slice() // 或者 let arr2 = arr.concat()

arr2[1] = 2
arr2[2].username = '6666'
console.log(arr1, arr2)

Arraysliceconcat 方法不修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组

深拷贝

  1. 扩展运算符,也可以进行 浅拷贝
  • 序列化 JSON.parse(JSON.stringify())
  • 缺点:虽然可以实现数组或对象深拷贝,但不能处理函数
  1. 递归遍历 手写实现
javascript 复制代码
// 定义检测数据类型的功能函数
function checkedType(target){
    return Object.prototype.toString.call(target).slice(8,-1)
}

// 实现深度克隆---对象/数组
function clone(target){
    // 判断拷贝的数据类型
    // 初始化变量result 成为最终克隆的数据
    let result,targetType = checkedType(target)
    if(targetType === 'Object'){
        result = {}
    }else if(targetType === 'Array'){
        result = []
    }else{
        return target
    }
    // 遍历目标数据
    for(let i in target){
        // 获取遍历数据结构的每一项值
        let value=target[i]
        // 判断目标结构里的每一值是否存在对象/数组
        if(checkedType(value) === 'Object' || checkedType(value) === 'Array'){ //对象/数组里嵌套了对象/数组
            // 继续遍历获取到value值
            result[i] = clone(value)
        }else{ //获取到value值是基本的数据类型或者是函数
            result[i] = value;
        }
    }
    return result
}

原理:递归遍历所有对象、数组,直到都是基本数据类型,然后再去复制,就是深拷贝

  1. 第三方函数库 loadsh
相关推荐
小巧的砖头15 分钟前
C#会重蹈覆辙吗?系列之2:反射及元数据的性能问题
开发语言·前端·c#
KaMeidebaby22 分钟前
卡梅德生物技术快报|蛋白的叠氮基修饰:实操解析:核酸模板耦合蛋白的叠氮基修饰实现靶蛋白定点共价标记
前端·人工智能·物联网·算法·百度
濮水大叔32 分钟前
在大型 Vue 项目中,如何有效管理复杂的状态?“散装版” vs “套装版”
前端·vue.js·typescript
玄星啊41 分钟前
可修改:代码的生存底线
前端·ai编程
没落英雄1 小时前
3. DeepAgents 实战 - Memory Skills 与上下文工程
前端·人工智能·架构
Bigger1 小时前
对不起!我错怪你了,UnoCSS:一次和 AI 一起排查 DevTools 卡顿的经历
前端·css·人工智能
laowang3572 小时前
依赖故障时,日志体系需要埋哪些关键节点才能快速定位是安装失败、解析失败还是运行时缺失?
前端·javascript·vue.js·webpack·node.js
倾颜2 小时前
AI Mind 的单线程短期记忆设计:如何压缩、整理并控制当前会话上下文
前端·langchain·llm
u0143781083 小时前
行内块元素之间的空白
前端·html
Lsx_3 小时前
基于 Claude Code 的 AI 编程工作流探索
前端·ai编程·claude