javascript中赋值、浅拷贝、深拷贝的区别及实例详解

  • 时间:2020-04-24 20:16 作者:loushumei 来源: 阅读:578
  • 扫一扫,手机访问
摘要:赋值当把一个对象a赋值给另外一个对象b时,赋的值是对象a在栈中的地址,而不是堆中的数据。let a={ name:'xiaoming', age:21, grade:{ language:60, math:81, english:99,

赋值

当把一个对象a赋值给另外一个对象b时,赋的值是对象a在栈中的地址,而不是堆中的数据。

let a={    name:'xiaoming',    age:21,    grade:{        language:60,        math:81,        english:99,        science:94    },}let b=ab.name='xiaowang'b.grade.language=90console.log('a',a)console.log('b',b)
赋值.png

结果分析:对象b和对象a指向同一地址,无论哪个对象发生改变,另外一个对象都会联动变化.

浅拷贝

浅拷贝它会创立一个新对象,不会指向同一个地址,只会赋值制对象的非对象属性
(假如属性是基本类型,拷贝的就是基本类型的值;假如属性是内存地址(引用类型),拷贝的就是内存地址)

ES6中有个浅拷贝的方法Object.assign(target, ...sources)。
let a = {    name: '小明',     age: 21,    grade: {        language: 78,        math: 81,        english: 99,        science: 94    },}let b = {}Object.assign(b,a)b.name = '小花' b.grade.english = 9 console.log('a', a)console.log('b', b)
浅拷贝.png

结果分析:
b对象改变 name的值和grade对象,a对象只有grade对象的值发生改变,name未受影响。
由于,name是基本类型,b改变自身值,a 不会改变;而grade是一个对象,为引用类型,b拷贝的是该对象的地址,与a指向同一个地址,所以b改变grade对象的值时,a也发生变化。

深拷贝

深拷贝会另外拷贝一份一个一模一样的对象,但是不同的是会从堆内存中开拓一个新的区域存放新对象,新对象跟原对象不再共享内存,修改赋值后的对象b不会改到原对象a。

实现方式

1、JSON.parse(JSON.stringify())

原理

用JSON.stringify将JSON对象转成JSON字符串,
再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开拓新的栈,实现深拷贝。

缺点

因为用到了JSON.stringify(),这也会导致一系列的问题,由于要严格遵守JSON序列化规则:原对象中假如含有Date对象,JSON.stringify()会将其变为字符串,之后并不会将其复原为日期对象。或者是含有RegExp对象,JSON.stringify()会将其变为空对象,属性中含有NaN、Infinity和-Infinity,则序列化的结果会变成null,假如属性中有函数,undefined,symbol则经过JSON.stringify()序列化后的JSON字符串中这个键值对会消失,由于不支持。

2、手写递归方法

递归方法实现深度克隆

/** * 深拷贝 * @param {Object} obj 要拷贝对象 */function deepClone(obj = {}) {    if (typeof obj !== 'object' || obj == null) {        // 不是对象,或者者是null        return obj    }    //初始化返回结果    let result    if (obj instanceof Array) {        result =[]    }else{        result = {}    }    for (const key in obj) {        //保证key不是原型的属性        if (obj.hasOwnProperty(key)) {             //递归调用!!            result[key] = deepClone(obj[key])        }    }    //返回结果    return result}
深拷贝.png

结果分析:b对象改变 name的值和grade对象,a均未受到影响,
以为b跟a不共享内存地址,是从堆内存中开拓一个新的区域存放的新对象。

  • 全部评论(0)
最新发布的资讯信息
【系统环境|】2025含金量排名前十计算机专业证书(2025-10-15 20:51)
【系统环境|】你有白帽众测 我有黑帽雇佣(2025-10-15 20:50)
【系统环境|】印度理工学院成功开发出针对5G网络攻击的最新软件解决方案(2025-10-15 20:49)
【系统环境|】道德黑客与黑客教程(2025-10-15 20:49)
【系统环境|】苹果翻车!macOS 15 竟藏“后门”,黑客能直接偷你所有密码(2025-10-15 20:47)
【系统环境|】解密“被墙”玄学:为什么我的网络方案能做到长期稳定?(2025-10-15 20:46)
【系统环境|】NAS软路由/防火墙/网络安全需要注意哪些?如何保护你的网络设备(2025-10-15 20:45)
【系统环境|】你真的理解防火墙吗?(2025-10-15 20:44)
【系统环境|】苹果手机一键换机教程详解(2025-10-15 20:44)
【系统环境|】二手iPhone到手后怎么快速验机?(2025-10-15 20:43)
手机二维码手机访问领取大礼包
返回顶部