ES6深拷贝与浅拷贝

  

小感在前

  

反应学习与开发过程要经历一个相当长的准备阶段,此前看阮一峰老师的文章中,他就特别提到这一点。但是,由于反应框架或者说是一种优秀的前端架构实在太诱人,所以,掌握这项技术所涉及的技术栈过程中经历的任何苦恼都是值得的。在还没有全面掌握这项技术的不断探索过程中,如果包括后端的一部分在内(例如node . JS和表达等,还有一些数据库及API知识),至少要有几十部分,仅限于核心的算起来也有十多项吧。
作为一个基础部分,ES6势在必学。此前,我曾得意于自己已经掌握了一定程度的JS知识,但是在匆读阮老师的《ES6标准入门》一书后才感觉自己落后许多了。同时,在阅读本书的过程中,也发现:这本书或者整个ES6,的确是为着眼于将来的“一统前后端”的大项目作准备的,因此,重复地专门学习这个语言是没有必要的。这是一本案头书,需要什么时再读什么更合适。
本文罗列的就是在本人在学习回来的过程中在遭遇到JS的深浅拷贝过程中总结的相关内容。太匆忙与粗略,仅供同学们参考。

  

JavaScript中变量的赋值

  

<强>结论:JavaScript中变量的赋值分为“传值”与“传址”。

基本数据类型的赋值,就是“传值”;而引用类型变量赋值,实际上是“传址”。
基本数据类型变量的赋值,比较,只是值的赋值和比较,也即栈内存中的数据的拷贝和比较,参见如下代码:

  
 <代码> var num1=123;
  var num2=123;
  var num3=num1;
  num1===num2;//正确的
  num1===num3;//正确的
  num1=456;
  num1===num2;//错误
  num1===num3;//错误 
  

引用数据类型变量的赋值,比较,只是存于栈内存中的堆内存地址的拷贝,比较,参加如下代码:

  
 <代码> var arr1=(1、2、3);
  var arr2=(1、2、3);
  var arr3=arr1;
  arr1===arr2;//错误
  arr1===arr3;//正确的
  arr1=(1、2、3);
  arr1===arr2;//错误
  arr1===arr3;//错误 
  

JavaScript中变量的拷贝

  

JavaScript中的拷贝区分为“浅拷贝”与“深拷贝”。

  

浅拷贝

  

<强>浅拷贝只会将对象的各个属性进行依次复制,并不会进行递归复制,也就是说只会进行赋值目标对象的第一层属性。

  

对于目标对象第一层为基本数据类型的数据,就是直接赋值,即“传值”;而对于目标对象第一层为引用数据类型的数据,就是直接赋存于栈内存中的堆内存地址,即“传址”。

  

深拷贝

  

<强>深拷贝不同于浅拷贝,它不但拷贝目标对象的第一层属性,而且还递归拷贝目标对象的所有属性。

  

一般来说,在JavaScript中考虑复合类型的深层复制的时候,往往就是指对于日期、对象与数组这三个复合类型的处理。我们能想到的最常用的方法就是先创建一个空的新对象,然后递归遍历旧对象,直到发现基础类型的子节点才赋予到新对象对应的位置。

  

不过这种方法会存在一个问题,就是JavaScript中存在着神奇的原型机制,并且这个原型会在遍历的时候出现,然后需要考虑原型应不应该被赋予给新对象。那么在遍历的过程中,我们可以考虑使用hasOwnProperty方法来判断是否过滤掉那些继承自原型链上的属性。

  

Object.assign

  

对象。分配方法可以把任意多个的源对象所拥有的自身可枚举属性拷贝给目标对象,然后返回目标对象。
注意:

  

对于访问器属性,该方法会执行那个访问器属性的getter函数,然后把得到的值拷贝给目标对象,如果你想拷贝访问器属性本身,请使用Object.getOwnPropertyDescriptor()和Object.defineProperties()方法;
字符串类型和符号类型的属性都会被拷贝;
在属性拷贝过程中可能会产生异常,比如目标对象的某个只读属性和源对象的某个属性同名,这时该方法会抛出一个TypeError异常,拷贝过程中断,已经拷贝成功的属性不会受到影响,还未拷贝的属性将不会再被拷贝;
该方法会跳过那些值为null或未定义的源对象,

  

利用JSON进行忽略原型链的深拷贝

  

<代码> var dest=JSON.parse (JSON.stringify(目标));

  

同样的它也有缺点:
该方法会忽略掉值为未定义的属性以及函数表达式,但不会忽略值为零的属性。

  

借助于Lodash的合并方法

  

在回家的开发中的一个应用是借助于Lodash的合并方法可以实现深拷贝,达到管理范式化数据的目的,示例代码如下:

ES6深拷贝与浅拷贝