你所不知道的 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
相关推荐
晨光321113 小时前
Day34 模块与包的导入
java·前端·python
BD_Marathon14 小时前
Vue3_关于CSS样式的导入方式
前端·css
苹果电脑的鑫鑫14 小时前
vue和react缩进规则的配置项如何配置
前端·vue.js·react.js
BD_Marathon14 小时前
Vue3_工程文件之间的关系
前端·javascript·vue.js
weibkreuz14 小时前
模块与组件、模块化与组件化的理解@3
开发语言·前端·javascript
拾忆,想起14 小时前
单例模式深度解析:如何确保一个类只有一个实例
前端·javascript·python·微服务·单例模式·性能优化·dubbo
RealizeInnerSelf丶14 小时前
Web 网页如何唤起本地 Windows 应用并传递参数(含 Electron 自动注册 + 手动配置指南)
前端·windows
IT_陈寒14 小时前
Redis 性能优化实战:5个被低估的配置项让我节省了40%内存成本
前端·人工智能·后端
chilavert31814 小时前
技术演进中的开发沉思-261 Ajax:动画优化
前端·javascript·ajax
尘心cx14 小时前
前端-APIs-day3
开发语言·前端·javascript