博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浅拷贝与深拷贝
阅读量:5330 次
发布时间:2019-06-14

本文共 2195 字,大约阅读时间需要 7 分钟。

  数据类型:说到拷贝,就首先需要谈谈堆栈和数据类型了,数据类型分为基本数据类型和引用数据类型,基本数据类型包括number,string,boolean,null 和 undefined这五类,而引用数据类型是由基本数据类型组成的复杂的对象,而深拷贝本身只针对较为复杂的object类型的数据。

  堆和栈内存:接下来说一下堆栈的存储空间,基本数据类型的名和值是都存在栈内中的,即有名可以直接读出值;而对于引用数据类型,它的名也是存在栈内存中,而它的真正的值是存在堆内存中的,那么它的名和值是怎么联系起来的呢,就是通过也存在栈内存中的真正的值在堆内存中的存储路径,即引用类型的数据在栈中存储的是名和值对应的引用地址。

  深拷贝和浅拷贝:

1、使用数据类型

  深拷贝和浅拷贝只针对像 ObjectArray 这样的复杂对象的,String,Number等简单类型不存在深拷贝。

2、浅拷贝

  
因为浅拷贝只会将对象的各个属性进行依次复制,并不会进行递归复制。在JavaScript中,对于
Object
Array这类引用类型值,当从一个变量向另一个变量复制引用类型值时,这个值的副本其实是一个指针,两个变量指向同一个堆对象,改变其中一个变量,另一个也会受到影响。所以浅拷贝会导致
obj.arr
shallowObj.arr 指向同一块内存地址,当修改
obj.arr的值时,
shallowObj.arr的值同样会被修改
 
3、深拷贝
  而深拷贝则不同,它不仅将原对象的各个属性逐个
复制出去,而且将原对象各个属性所包含的对象也依次采用深拷贝的方法
递归复制到新对象上。这就不会存在上面
obj
shallowObj
arr 属性指向同一个对象的问题。当修改
obj.arr的值时,
shallowObj.arr的值不会被修改,仍然为原值
 
  实现深拷贝的方法:
  1、可以递归去复制数据的所有层级的属性
function cloneDeeply(obj){
  //定义一个拷贝的对象 let objClone = Array.isArray(obj)?[]:{};   //传入的数据是对象类型的 if(obj && typeof obj==="object"){ for(key in obj){
        //判断是否是自身的属性方法,所有函数和原型成员会被有意忽略 if(obj.hasOwnProperty(key)){ //判断ojb子元素是否为对象,如果是,递归复制 if(obj[key]&&typeof obj[key] ==="object"){ objClone[key] = deepClone(obj[key]); }else{ //如果不是,简单复制 objClone[key] = obj[key]; } } } } return objClone;}
 
  2、
JSON.parse(JSON.stringify(obj))方法实现深拷贝
  该用法简单,然而使用这种方法会有一些隐藏的坑:因为在序列化JavaScript对象时,所有函数和原型成员会被有意忽略。故只能拷贝纯json的,不能拷贝包含函数的对象)。
通俗点说,
JSON.parse(JSON.stringfy(X)),其中X只能是
Number
String
Boolean
Array, 扁平对象,即那些能够被 JSON 直接表示的数据结构。
  
function cloneDeeply(obj){    let _obj = JSON.stringify(obj),        objClone = JSON.parse(_obj);    return objClone}
  3、另外JQuery也提供了一个对象扩展的方法extend进行属性的深浅复制,可配置  

  jQuery.extend() 函数用于将一个或多个对象的内容合并到目标对象。

  注意:1. 如果只为$.extend()指定了一个参数,则意味着参数target被省略。此时,target就是jQuery对象本身。通过这种方式,我们可以为全局对象jQuery添加新的函数。

     2. 如果多个对象具有相同的属性,则后者会覆盖前者的属性值。

  4、特殊情况
  slice的一级是深拷贝,多级则是浅拷贝(记住深拷贝是拷贝对象所以层级的属性)
  es6中的展开符号... 也是浅拷贝
参考链接:https://www.jianshu.com/p/68e563c54f63
       https://www.cnblogs.com/echolun/p/7889848.html#undefined

转载于:https://www.cnblogs.com/gopark/p/10471489.html

你可能感兴趣的文章
介绍Win7 win8 上Java环境的配置
查看>>
Linux设置环境变量的方法
查看>>
构建自己的项目管理方案
查看>>
利用pca分析fmri的生理噪声
查看>>
div水平居中且垂直居中
查看>>
epoll使用具体解释(精髓)
查看>>
AndroidArchitecture
查看>>
安装Endnote X6,但Word插件显示的总是Endnote Web"解决办法
查看>>
python全栈 计算机硬件管理 —— 硬件
查看>>
大数据学习
查看>>
简单工厂模式
查看>>
Delphi7编译的程序自动中Win32.Induc.a病毒的解决办法
查看>>
Objective-C 【关于导入类(@class 和 #import的区别)】
查看>>
倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-点击运行按钮进入到运行状态报错Error starting TwinCAT System怎么办 AdsWarning1823怎么办...
查看>>
【转】javascript 中的很多有用的东西
查看>>
Android 监听返回键、HOME键
查看>>
Android ContentProvider的实现
查看>>
sqlserver 各种判断是否存在(表名、函数、存储过程等)
查看>>
给C#学习者的建议 - CLR Via C# 读后感
查看>>
Recover Binary Search Tree
查看>>