JavaScript对象的深拷贝

前言

-路漫漫其修远兮,我将上下而求索。前端

在JavaScript数据类型分为基础类型和引用类型,而引用类型又称为对象,可见了解对象是咱们真正掌握JavaScript语言的必备技能。本章主要与你们一块儿去探索JavaScript对象的一些常常被咱们忽略的以及难以理解的知识。好了,废话很少说让咱们一块儿进入JavaScript对象的世界吧。编程

基本概念

  • 我的理解:深浅拷贝在JavaScript中只是对于引用类型来讲的,由于在JavaScript中基本数据类型是经过值传递的,因此他们不存在深拷贝一说。
  • 对象的浅拷贝:即只复制对象在栈内存中的保存的地址值,例如咱们直接用赋值符号拷贝另外一个对象的值。
  • 对象的深拷贝:复制对象存在堆内存中的实际值而且从新在栈内存中生成一份指向新堆内存中的地址值。
  • 缘由:JavaScript中的引用类型的数据是被存放在堆内存中的,他们在栈内存中的变量只是保存了一个指向对堆内存中值的指针(相似与c中的指针),所以咱们在访问引用类型的数据时只能先从栈中取出对象的指针地址,而后才会从堆内存中取得对象的数据。这也是JavaScript对象用赋值符号只能复制指针地址的缘由。

为什么进行对象深拷贝

  • 若是只是对对象数据类型进行简单的浅拷贝,则新复制的值和老值会共用堆内存中的数据,致使值不肯定性,例如:
let a={
    val:"test"
}
console.log(a.val)//"test"
let b=a
b.val="test2"
console.log(a.val)//"test2"
console.log(b.val)//"test2"
复制代码

这也是致使前端显示异常的根本缘由之一json

  • 提升代码可维护性,多人合做开发时,共用某份是对象类型的数据若是只进行简单的浅拷贝则很影响他人。

深拷贝的方法

  • JSON.stringfy() => JSON.parse() 即将一个对象先解析为json 字符串而后再解析
let a={
    val:'test'
}
let b=JSON.parse(JSON.stringfy(a))
复制代码

优势:操做简单。数组

缺点:1.若是对象很大会占用内存 2.对于复杂的对象类型(即属性是诸如 Map, Set, RegExp, Date, ArrayBuffer,function和其余内置类型),在进行序列化时会丢失。 丢失属性。3.没法进行对象的循环处理。bash

  • 使用object.assign()来实现:
let originobj= {
  'name': 'test',
  'weight': 50
};
let newobj = Object.assign({}, originobj, {
  'test': '111'
});
newobj.age = 60;
console.log('originobj', originobj); //{name: "test", weight: 50}
console.log('newobj', newobj); //{name: "test", weight: 50, test: "111", age: 60}

复制代码

优势:方便快捷 不会丢失原数据 缺点:只能复制简单的对象(),即Object.assign()拷贝的只是属性值 注意:若是对象中的属性仍是对象则Object.assign()不会进行值拷贝,只能进行引用拷贝编程语言

  • 为了解决JSON和assign复制带来的问题,咱们能够采用循环递归复制,即在遍历赋值对象属性的时候,遇到属性是引用类型的,则把这个属性展开赋值,以下代码所示:
function cloneDeep(newobj={},originObj){
    for(let key in originObj){
        //判断是不是对象类型
        if(originObj[key] && originObj[key] instanceof object){
            //递归将对象类型赋值给新数组
            newobj[key] = cloneDeep(originObj[key])
        }else{
            newobj[key] = originObj[key]
        }
    }
    return newobj
}
let obj = {a:{b:'test'},c:"test2"}
//此时彻底copy了obj的值
let obj1 = cloneDeep(obj)//{a:{b:'test'},c:"test2"}
复制代码

总结

在编程的世界中熟悉某一门语言的基本要求就是掌握这门语言定义的数据类型,不一样的语言中所定义的数据类型每每不一样。这也是咱们同时掌握多中编程语言的难点。但幸运的是他们底层设计原理都是相互借鉴的,这也成为了咱们可以掌握夺门语言的关键点之一。ui

相关文章
相关标签/搜索