javascript实现引用数据类型的深拷贝和浅拷贝详解

关于引用类型值的详解,请看另一篇随笔 https://www.cnblogs.com/jinbang/p/10346584.html

深拷贝和浅拷贝,也就是引用数据类型栈和堆的知识点。深浅拷贝的原型都是Object,深拷贝指向的栈内存不一样,浅拷贝指向的栈内存一样):

如何区分深拷贝与浅拷贝,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B没有发生变化,说明是深拷贝。如果B也跟着发生了变化,说明是浅拷贝。

      let obj = { name: "jin", arr: ["red","blue","black"]};
      let obj1 = {};
      Object.defineProperties(obj1, Object.getOwnPropertyDescriptors(obj)); // 深拷贝
      Object.assign(obj1, obj); // 深拷贝
      obj1 = JSON.parse(JSON.stringify(obj)); // 深拷贝
      obj1 = deepCopy(obj); // 使用到深拷贝函数
      obj1 = obj; // 浅拷贝
      obj1 = Object.assign(obj); // 浅拷贝

下面是deepCopy()深拷贝函数,其中使用到了判断变量的类型函数

      // 判断变量的类型
      function getType(obj){
        let str = Object.prototype.toString.call(obj); // 检测基本类型值,引用类型值的类型
        let map = {
          ‘[object Boolean]‘: ‘boolean‘,
          ‘[object Number]‘: ‘number‘,
          ‘[object String]‘: ‘string‘,
          ‘[object Function]‘: ‘function‘,
          ‘[object Array]‘: ‘array‘,
          ‘[object Date]‘: ‘date‘,
          ‘[object RegExp]‘: ‘regExp‘,
          ‘[object Undefined]‘: ‘unfefined‘,
          ‘[object Null]‘: ‘null‘,
          ‘[object Object]‘: ‘object‘
        };
        if(obj instanceof Element){
          return ‘element‘;
        }
        return map[str];
      }

      // 深拷贝函数
      function deepCopy(p){
        let obj;
        let str = getType(p);
        if(str === ‘array‘){

          obj = [];
          for(let i=0;i<p.length;i++){
            // obj.push(p[i]); // 不能这样写,因为会把array的堆内存也会复制过去
            obj.push(arguments.callee(p[i])); //回调自己
          }
        }else if(str === ‘object‘){
          obj = {};
          for(let i in p){
            // obj[i] = p[i]; // 不能这样写,因为会把object的堆内存也会复制过去
            obj[i] = arguments.callee(p[i]); //回调自己
          }
        } else {
          return p;
        }
        return obj;
      }

需要特别注意的是,使用JSON.parse(JSON.stringify(x))不是一个很好的选择,也算是它们的坑吧:

对象是由构造函数生成的:会丢弃对象的constructor,因为JSON.stringify()只能序列化对象的可枚举的自有属性

时间对象:变成字符串

RegExp,Error对象:变成空对象

函数,undefined:会被丢失

NaN,Infinity和-Infinity:变成null

function Person(name){
      this.name = name;
    }
    var person = new Person(‘liai‘);

    var test = {
      name: ‘jin‘,
      person: person, //对象是由构造函数生成的:会丢弃对象的constructor
      date: new Date(), //序列化后返回是字符串,不是时间对象
      regexp: new RegExp(‘\\w+‘), //序列化后返回空对象:{}
      err: new Error(),  //序列化后返回空对象:{}
      fun: function(){}, //序列化后会丢失
      undef: undefined, //序列化后会丢失
      nun: NaN, //序列化后返回null
    };
    console.log(test);
    console.log(JSON.parse(JSON.stringify(test)));

原文地址:https://www.cnblogs.com/jinbang/p/10346649.html

时间: 2024-10-14 16:50:42

javascript实现引用数据类型的深拷贝和浅拷贝详解的相关文章

【转】 c++拷贝构造函数(深拷贝,浅拷贝)详解

c++拷贝构造函数(深拷贝,浅拷贝)详解 2013-11-05 20:30:29 分类: C/C++ 原文地址:http://blog.chinaunix.net/uid-28977986-id-3977861.html 一.什么是拷贝构造函数      首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a=100; int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.  下面看一个类对象拷贝的简单例子. #include<iostream

**Python中的深拷贝和浅拷贝详解

Python中的深拷贝和浅拷贝详解 这篇文章主要介绍了Python中的深拷贝和浅拷贝详解,本文讲解了变量-对象-引用.可变对象-不可变对象.拷贝等内容. 要说清楚Python中的深浅拷贝,需要搞清楚下面一系列概念: 变量-引用-对象(可变对象,不可变对象)-切片-拷贝(浅拷贝,深拷贝) [变量-对象-引用] 在Python中一切都是对象,比如说:3, 3.14, 'Hello', [1,2,3,4],{'a':1}...... 甚至连type其本身都是对象,type对象 Python中变量与C/

IOS中复制对象的用法及深拷贝和浅拷贝详解

亲爱的网友,我这里有套课程想和大家分享,如果对这个课程有兴趣的,可以加我的QQ2059055336和我联系. 课程内容简介 我们软件是基于移动设备的.所以我们必然的选择了安卓作为我们的开发工具.课程中,我们将简要的介绍Android的基本概念,然后进行我们的实战开发.在开发中,大家讲学习到基本的组件,适配UI,数据的存储,多线程下载,开机广播,闹钟提醒,短信发送等实际项目开发中碰到的有用的知识点.通过课程学习,让大家能够掌握Android软件开发的流程,注意点,及优化.帮助大家迅速的掌握Andr

Javascript学习之深拷贝和浅拷贝详解

在JavaScript 中,存在着这样的两种拷贝方式.分别是:深拷贝和浅拷贝,这两种拷贝在实际中非常的常见,如果读者是一个阅读源码的爱好者,相信多多少少对深拷贝和浅拷贝有所了解.本文和大家分享的就是深拷贝和浅拷贝相关内容,一起来看看吧,希望对大家 学习javascript有所帮助. 一.浅拷贝 浅拷贝在现实中最常见的表现在赋值上面,例如 <!DOCTYPE html> <html lang="en"> <head> <meta charset=

c++拷贝构造函数(深拷贝,浅拷贝)详解

一.什么是拷贝构造函数      首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a=100; int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.  下面看一个类对象拷贝的简单例子. #include<iostream> using namespace std; class CExample { private: int a; public: //构造函数 CExample(int b) { a=b; printf("con

iOS开发——深拷贝与浅拷贝详解

深拷贝和浅拷贝这个问题在面试中常常被问到,而在实际开发中,只要稍有不慎,就会在这里出现问题.尤其对于初学者来说,我们有必要来好好研究下这个概念.我会以实际代码来演示,相关示例代码上传至 这里 . 首先通过一句话来解释:深拷贝就是内容拷贝,浅拷贝就是指针拷贝. 深拷贝就是拷贝出和原来仅仅是值一样,但是内存地址完全不一样的新的对象,创建后和原对象没有任何关系.浅拷贝就是拷贝指向原来对象的指针,使原对象的引用计数+1,可以理解为创建了一个指向原对象的新指针而已,并没有创建一个全新的对象. (1)非容器

JS的 new 原理,call原理,基本数据类型,引用数据类型,深拷贝,浅拷贝

在用构造函数 new 出来一个对象时的思考,以及逐步解决理清思路的过程. https://blog.csdn.net/zhouziyu2011/article/details/60143385  new 的分步详情 https://blog.csdn.net/qq_28978893/article/details/79272422   深浅拷贝 https://blog.csdn.net/zhouziyu2011/article/list/1?t=1 原文地址:https://www.cnblo

OC细节 - 1.深拷贝与浅拷贝详解

概述 拷贝:复制一个与源对象内容相同的对象 实现拷贝,需要遵守以下两个协议 NSCopying NSMutableCopying 拷贝返回对象的种类 可变,mutableCopy消息返回的对象 不可变,copy消息返回的对象 拷贝的种类 浅拷贝,只是复制了一个指向源对象的指针,未创建对象,未分配内存 深拷贝,复制了源对象,创建了新对象,分配了内存 注意 系统对容器类的对象与非容器类的对象的内存处理是不同的,即当一个没有被其他对象强引用的对象从容器中移除后,该对象就销毁 Copy与Retain c

Python学习教程:Python列表赋值,复制,深拷贝及5种浅拷贝详解

Python学习教程:Python列表赋值,复制,深拷贝及5种浅拷贝详解 概述 在列表复制这个问题,看似简单的复制却有着许多的学问,尤其是对新手来说,理所当然的事情却并不如意,比如列表的赋值.复制.浅拷贝.深拷贝等绕口的名词到底有什么区别和作用呢? 列表赋值 # 定义一个新列表l1 = [1, 2, 3, 4, 5]# 对l2赋值l2 = l1print(l1)l2[0] = 100print(l1) 示例结果: [1, 2, 3, 4, 5][100, 2, 3, 4, 5] 可以看到,更改赋