你所不知道的 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
相关推荐
F2E_Zhangmo16 小时前
基于cornerstone3D的dicom影像浏览器 第三章 拖拽seriesItem至displayer上显示第一张dicom
前端·javascript·cornerstone·cornerstone3d·cornerstonejs
gnip21 小时前
Jst执行上下文栈和变量对象
前端·javascript
excel1 天前
🐣 最简单的卷积与激活函数指南(带示例)
前端
醉方休1 天前
npm/pnpm软链接的优点和使用场景
前端·npm·node.js
拉不动的猪1 天前
简单回顾下Weakmap在vue中为何不能去作为循环数据源,以及替代方案
前端·javascript·vue.js
How_doyou_do1 天前
数据传输优化-异步不阻塞处理增强首屏体验
开发语言·前端·javascript
奇舞精选1 天前
超越Siri的耳朵:ASR与Whisper零代码部署实战指南
前端·人工智能·aigc
奇舞精选1 天前
Nano Banana 如何为前端注入 AI 控制力
前端·aigc
一支鱼1 天前
基于 Node.js 的短视频制作神器 ——FFCreator
前端·node.js·音视频开发
DT——1 天前
前端登录鉴权详解
前端·javascript