• 前端随心记---------深拷贝与浅拷贝


     深拷贝与浅拷贝

      在前端js里面的数据类型分为两大类:

    1.基本数据类型(数据传递:值拷贝)

    var a = 12;
    
    var b = a; // 赋值操作,是把 a 地址里面对应的值赋值给了 变量b 所对应的地址空间。
    
    b = 24;
    
    a; // 不会受到影响 数据传递:值拷贝

    2.复合数据类型(引用数据类型)

    var obj = {id: 1, username: 'andy', todos: ['吃饭', '睡觉']}; // 复合数据类型
     
    var xiaoming = obj; 
    // 复合数据类型,地址的拷贝,现在 xiaoming 变量 和 obj 变量,同一个地址空间
    // 好处:节省内存空间。
    // 弊端:数据之间彼此受到影响。(存在在风险)
    
    xiaoming.username = 'xiaoming';
    
    // xiaoming 变量
    console.log(xiaoming); // xiaoming
    
    // 隐患
    console.log(obj.username); // xiaoming

             针对这种问题,我们把上面的这种现象叫做:浅拷贝。如果要解决这种问题,我们需要使用深拷贝进行实现:把复合数据类型(对象),将对象的key和value换成基本数据类型复制拷贝。

    var tmp = {};
    function copy( source ){
        for(var attr in source ){
            if( typeof  source[attr] === 'object' || typeof  source[attr] === 'array'){
                copy(source[attr]);
            }else{
                // 基本的数据类型的拷贝
                 tmp[attr] = source[attr]; 
            }   
        }
    }

           根据案例,递归代码(深拷贝:值拷贝),程序复杂不好理解,不好书写,并且存在性能问题,函数的使用,都需要开启内存空间,因此,减少递归的使用。

      

    var obj = {id: 1, username: 'andy', todos: ['吃饭', '睡觉']}
    
    var xiaoming = JSON.parse( JSON.stringify(obj) );    先把对象转化成字符串,在转化成Javascript对象

      以上 虽然实现深拷贝,并且性能较好,但是存在一个问题:这种不能拷贝对象里面的方法,如果对象里面出现了方法,在使用JSON.stringify把方法丢失

      es6中也存在一种拷贝方式,下例:

    var obj = {id:1, name: 'andy'};
    
    // Object.assgin 把多个参数进行合并,返回一个新的对象
    var xiaoming = Object.assign({}, obj);
    
    xiaoming.name = 'xiaoming';
    
    console.log(xiaoming.name); //xiaoming
    
    console.log(obj.name);// andy

     但是这种拷贝存在弊端:1.浏览器兼容的问题    2.只实现第一层的深拷贝,其他的都不是深拷贝,只是浅拷贝。例如:

    var obj = {id:1, name: 'andy', todos: ['eat', 'sleep']};
    
    // Object.assgin 把多个参数进行合并,返回一个新的对象
    // Object.assgin 只实现一层的拷贝,如果对象的属性的值还是一个复合数据类型,完成的地址的引用(带来隐患)
    var xiaoming = Object.assign({}, obj);
    
    xiaoming.todos.push('dadoudou');
    
    xiaoming.name = 'xiaoming';
    
    console.log(xiaoming.todos); // [ 'eat', 'sleep', 'dadoudou' ]
    
    console.log(obj.todos); // 是否受到影响? 是  [ 'eat', 'sleep', 'dadoudou' ]

       如何解决这种深拷贝的问题呢?如何如何解决这种浅拷贝带来的性能问题和JSON.parse( JSON.stringify(obj) )代表的方法丢失问题?

      我们可以采取第三方的库来完成 深拷贝   如: loadsh.js  。 immutable.js 。underscrejs  。

     immutable 简介

             Immutable Data 就是一旦创建,就不能再被更改的数据。对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象。Immutable 实现的原理是 Persistent Data Structure(持久化数据结构),也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变。同时为了避免 deepCopy 把所有节点都复制一遍带来的性能损耗,Immutable 使用了Structural Sharing(结构共享),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。

    参考资料:

    https://www.jianshu.com/p/0fa8c7456c15
    https://github.com/immutable-js/immutable-js
     

     

       常见的数据类型和 api

    https://segmentfault.com/a/1190000010676878?utm_source=tag-newest
    1. List: 有序索引集,类似JavaScript中的Array。

    2. Map: 无序索引集(hash key-value键值对),类似JavaScript中的Object。

    3. Set: 没有重复值的集合。(数学上的集合)(集合三大特性:1. 无序性 2. 确定性(薛定谔的猫) 3. 唯一性)

    为什么 react要使用immutable.js?

    https://juejin.im/post/5d9f27666fb9a04e247c8ded
    集思广益,仅供学习,侵权即删!!
  • 相关阅读:
    dynamic_debug和pr_debug()打印_高通平台
    Linux内核中的数据结构杂记
    Binder杂记
    内核中读写文件
    记一次阿里云ECS中Docker容器内无法连接RDS内网地址的故障解决
    mac上使用sips命令快速裁剪、旋转、翻转图片
    最新Android手机导出ANR、tombstones文件
    Android日期格式控制—— DateUtils
    addr2line的用法
    Spring-Cloud 学习笔记-(6)Feign
  • 原文地址:https://www.cnblogs.com/hudunyu/p/11657255.html
Copyright © 2020-2023  润新知