博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS - 浅拷贝与深拷贝的理解以及简单实现方法
阅读量:6370 次
发布时间:2019-06-23

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

前几天撸项目代码时, 由一个技术点间接牵扯出了这东西. 所以就来总结一下.

深拷贝

  拷贝对象每个层级的属性.
  作用的对象是 js中引用类型的对象,基本类型没有涉及.
  本质上将引用类型的对象在堆上重新开辟一块新的空间进行存放.

1 var p_1 = {name: '病猫', age: 22};2 var p_3 = {name: p_1.name, age: p_1.age};3 p_3.name = "迪迦";4 console.log("p_1", p_1); //p_1 {name: "子川", age: 22}5 console.log("p_3", p_3); //p_3 {name: "迪迦", age: 22}

浅拷贝

  对于引用类型的对象, 浅拷贝是在栈上重新定义了一个指针,指向的位置却依然是堆中同一对象.  

1 var p_1 = {name: '病猫', age: 22};2 var p_2 = p_1;3 p_2.name = "子川";4 console.log("p_1", p_1); //p_1 {name: "子川", age: 22}5 console.log("p_2", p_2); //p_2 {name: "子川", age: 22}

实现方法

   ①: JSON的序列化与反序列化

1 let o = JSON.parse(JSON.stringify(obj));2 //但是obj中若含有 function, undefined, 正则表达式 时,3 //o 中 function, undefined不存在, 正则表达式对应变成了 {};

   ②: 递归   (对日期和正则做了简单处理,)

1 function deepHandle(obj) { 2         let tempObj = Array.isArray(obj) ? [] : {}; 3         if (obj && typeof obj === "object") { 4             for (key in obj) { 5                 if (obj.hasOwnProperty(key)) { //判断自身属性 6                     if (obj[key] && typeof obj[key] === "object") {  //是对象类型 7                         let type = Object.prototype.toString.call(obj[key]).slice(8, -1); //具体对象类型 8                         console.log("类型", type); 9                         //Date 与 RegExp 不处理的话, 拷贝之后会成 {}, 10                         if (type === 'Date') {11                             tempObj[key] = new Date(obj[key]);12                         } else if (type === 'RegExp') {13                             tempObj[key] = new RegExp(obj[key]);14                         } else {15                             tempObj[key] = deepHandle(obj[key]);16                         }17                     } else {18                         tempObj[key] = obj[key];19                     }20                 }21             }22         }23         return tempObj;24     }25     let obj = {26         a: '于康',27         b: {28             age: 21,29             city: "山西",30             n: [1,2,3, new Date(), /234/igm]31         },32         c: undefined,33         d: null,34         e: true,35         f: new Date(),36         h: {},37         i: /234/igm,38         toEat: function() {39             console.log("吃法")40         }41     }42     let deepObj = deepHandle(obj);43     let deepObj2 = JSON.parse(JSON.stringify(obj));44     deepObj.i = /123/igm;45     console.log("obj", obj);46     console.log("deepObj", deepObj);47     console.log("deepObj2", deepObj2);

 

补充一下数据类型

  基本数据类型 (number, string, boolean, null, undefined).
    ①:按值访问,即可操作保存在变量中的实际值.
    ②:值是不可变的,
    ③:名-值存储在栈内存中.
 1 let name = "病猫"; 2 name = "迪迦"; 3 //看似 name 的值发生了改变, 实际改变的是 指针指向; 

  引用数据类型 (即对象类型Object type. 如: Object, Array, Function, Date等)
 1 let obj = {name: "病猫", age: 22} 

    ①: 堆内存中存放引用数据类型的对象 (即 {name: "病猫", age: 22})

    ②: 栈内存中存放引用数据类型的变量名 (即 obj) 和 此对象的 引用地址(即 指针);
    ③: javascript 不允许直接访问与操作堆内存空间, 只能操作对象在栈中的引用地址

结尾

   以上内容是记录自己理解知识后的笔记, 若理解有误, 望您能指出. 感激不尽.      对于这个知识点,网上很多写的通俗易懂的文章(图文), 很Nice的.

转载于:https://www.cnblogs.com/yk95/p/10863197.html

你可能感兴趣的文章
几个常用且免费的接口
查看>>
jQuery文件上传插件 Uploadify更改错误提示的弹出框
查看>>
RHEL6下Apache与Tomcat整合
查看>>
Heartbeat+DRBD+MFS高可用
查看>>
要感谢那些曾经慢待你的人
查看>>
常见的global cache等待事件
查看>>
第 7 章 多主机管理 - 047 - 管理 Machine
查看>>
CentOS5和6的系统启动流程
查看>>
怎么看域客户端是否继承了组策略
查看>>
linux防止DDoS***
查看>>
6.4 Linked List 重做
查看>>
小米路由
查看>>
QT 学习 之 窗口拖拽 实现
查看>>
PHP的ftp文件,多文件上传操作类
查看>>
js中清空数组的方法
查看>>
python def说明
查看>>
Java根据IP获取国家省级地市信息
查看>>
自动安装系统及网络安装服务
查看>>
11g RAC 更改归档模式 ,归档文件存放在ASM 磁盘组
查看>>
Visual Studio安装项目中将用户选择的安装路径写入注册表的方法[转]
查看>>