javaScript深拷贝和浅拷贝的简单介绍

 更新时间:2022年05月06日 11:21:15   作者:程序猿布欧  
深浅拷贝知识在我们的日常开发中还算是用的比较多,下面这篇文章主要给大家介绍了关于javaScript深拷贝和浅拷贝的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

在了解深拷贝和浅拷贝之前,我们先梳理一下:

JavaScript中,分为基本数据类型(原始值)和复杂类型(对象),同时它们各自的数据类型细分下又有好几种数据类型

基本数据类型

数字Number 字符串String 布尔Boolean Null Undefined Symbols BigInt

基本数据类型在内存当中,是存储在栈Stack

在数据结构当中

  • 栈在内存上的分配的空间生命周期很短,当变量使用完毕,方法执行完成就被释放掉,因此在js当中,变量使用完毕之后,基本就被回收了,
  • 有一个场景比较例外,闭包的情况下,变量是始终存在内存当中不被释放.
  • 栈存储具有先进后出,后进先出的特点: 1,2,3,4,5,6 => 6,5,4,3,2,1

引用数据类型

日期Dete,对象Object,数组Array,方法Function, 正则regex,带键的集合:Maps, Sets, WeakMaps, WeakSets

引用数据类型与堆内存heap的一些关系

  • 在JavaScript中,不允许直接访问堆内存中的位置,不能直接操作对象的堆内存空间。
  • 对象的引用地址是存在栈内存中,在我们的日常编码过程中,操作对象的时候,读取对象的存在栈内存的引用地址而不是在堆中的对象,引用类型的值都是通过引用访问。

JavaScript中堆内存和栈内存简易示意图例

下面对于对象的操作,都可以参照上图进行思考

浅拷贝-深拷贝

浅拷贝

只是拷贝了某一层的属性,或者某一层,没有全部拷贝到另外的对象上

let userInfo = {
  name: "zhangsan",
  age: "29",
  say: function () {
    console.log("hello");
  },
  child: [
    {
      name: "zhangsan01",
    },
  ],
};

对象解构,只能拷贝第一层对象

// 对象解构...
let info = { ...userInfo };
info.name = "lisi";
info.child.name = "lisi001";
info.say();

console.log("userInfo", userInfo);
console.log("info", info);

userInfo和info中的child.name都改成了---->"lisi001"

Object.assign() 第一层是深拷贝,二级属性后就是浅拷贝

let info = {};
Object.assign(info, userInfo);
info.name = "lisi";
info.child.name = "lisi001";
console.log("userInfo", userInfo);
console.log("info", info);

JSON.parse(JSON.stringify());

对象可以复制,但是当属性是function时,没有复制到新的对象上,因此在日常的开发过程中,涉及到数组对象,使用JSON.parse(JSON.stringify());还是没问题的

let info = JSON.parse(JSON.stringify(userInfo));
info.name = "lisi";
info.child.name = "lisi001";
console.log("userInfo", userInfo);
console.log("info", info);

for in,第一层可以拷贝,第二层在修改的时候,还是使用的引用地址,前后的对象都发生了更改

let info = {};
for (let key in userInfo) {
  info[key] = userInfo[key];
}
info.name = "lisi";
info.child.name = "lisi001";
console.log("userInfo", userInfo);
console.log("info", info);

浅拷贝小结

以上浅拷贝方法,有些拷贝只能拷贝第一层,有些可以拷贝多层,

但是当属性类型是方法时,还是浅拷贝,

因此我们在开发中,使用浅拷贝,需要注意,同时,出了拷贝function,类似正则,date等数据类型没有一一列举,感兴趣的同学可以自己写一些demo,去校验更为复杂和数据类型更丰富的数据。

深拷贝

所有的属性都拷贝到新的对象上

使用递归遍历每一个属性,在递归遍历的时候,针对每一种数据类型处理和拷贝

lodash深拷贝方法,感兴趣的同学,可以去阅读lodash深拷贝的实现源码

文档地址:深拷贝cloneDeep https://www.lodashjs.com/docs/lodash.cloneDeep

更多方法,有待补充

结尾

当我们操作复杂数据类型的时候,都是在操作栈内存Stack的内存地址,指针指向对象在堆内存heap的数据。

传入的对象是使用对象字面量{}创建的对象还是由构造函数生成的对象

如果对象是由构造函数创建出来的,那么是否要拷贝原型链上的属性

如果要拷贝原型链上的属性,那么如果原型链上存在多个同名的属性,保留哪个

针对的数据类型,属性的数据类型,各自的缺陷,适用的业务场景,自己造轮子or使用原生方法,工具类

到此这篇关于javaScript深拷贝和浅拷贝的文章就介绍到这了,更多相关js深拷贝和浅拷贝内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

源码地址

码云 https://gitee.com/lewyon/vue-note

githup https://github.com/akari16/vue-note

相关文章

  • 详解webpack2异步加载套路

    详解webpack2异步加载套路

    这篇文章主要介绍了详解webpack2异步加载套路,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • javascript校验价格合法性实例(必须输入2位小数)

    javascript校验价格合法性实例(必须输入2位小数)

    这篇文章主要介绍了javascript校验价格合法性实例,其中价格必须是数字且必须输入2位小数,需要的朋友可以参考下
    2014-05-05
  • JS从数组中随机取出几个数组元素的方法

    JS从数组中随机取出几个数组元素的方法

    JS如何从一个数组中随机取出一个元素或者几个元素呢?其实方法很简单,下面小编给大家分享了JS随机取出几个数组元素的方法,非常不错,需要的朋友参考下
    2016-08-08
  • echarts折线图每段显示不同的颜色的实现

    echarts折线图每段显示不同的颜色的实现

    本文主要介绍了echarts折线图每段显示不同的颜色的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-09-09
  • JS highcharts动态柱状图原理及实现

    JS highcharts动态柱状图原理及实现

    这篇文章主要介绍了JS highcharts动态柱状图原理及实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • JS扩展类,克隆对象与混合类实例分析

    JS扩展类,克隆对象与混合类实例分析

    这篇文章主要介绍了JS扩展类,克隆对象与混合类,通过自定义extend,clone与augment函数实例分析了类的扩展,对象的克隆与混合类相关实现与使用技巧,需要的朋友可以参考下
    2016-11-11
  • Object的相关方法 和 js遍历对象的常用方法总结

    Object的相关方法 和 js遍历对象的常用方法总结

    这篇文章主要介绍了Object的相关方法 和 js遍历对象的常用方法,结合实例形式总结分析了Object对象操作的操作方法与js遍历的三种常用方法,需要的朋友可以参考下
    2023-05-05
  • js字母大小写转换实现方法总结

    js字母大小写转换实现方法总结

    本文是对js中字母大小写转换的实现方法进行了总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2013-11-11
  • js基于cookie方式记住返回页面用法示例

    js基于cookie方式记住返回页面用法示例

    这篇文章主要介绍了js基于cookie方式记住返回页面的用法,涉及javascript操作cookie及php针对cookie的判断技巧,需要的朋友可以参考下
    2016-05-05
  • js修改原型的属性使用介绍

    js修改原型的属性使用介绍

    原型(prototype)定义了特定类型的所有实例都可以访问的属性和方法,很多些情况下需要重新对原型中的属性赋值,下面为大家介绍下如何修改原型
    2014-01-01

最新评论