• 浅拷贝和深拷贝


    当我们进行浅拷贝时,拷贝基本数据类型和引用数据类型的情况是不一样的。

    为什么呢?因为两种情况下内存发生的变化不一样。

    1、拷贝基本数据类型举例:

    1     var video = 100;
    2     var copy = video;
    3     copy = 10000;
    4     console.log(video);     // 100
    5     console.log(copy);      // 10000

    我们发现修改copy的值,不会影响video。

    内存中发生什么呢?video相当于一个标识符,会为其分配一个内存地址,存储的值为100。拷贝给copy,vedio和copy都指向一个内存地址。然后给copy赋新值,会开辟新的内存地址。存在栈内存中。

     2、拷贝引用数据类型举例:

    1     var video = {
    2           like: 100
    3     };
    4     var copy = video;
    5     copy.like = 10000;
    6     console.log(video);
    7     console.log(copy);

    结果发现修改copy,会影响video。

     此时内存发生什么呢?video相当于一个标识符,会为其分配一个栈内存地址,这个内存地址提供一个新的引用地址指向堆内存中的值。

     我们可以通过什么方法进行浅拷贝?(注意是对象)

    1、惯用的方法,即赋值法 2、通过Object.assign() ,从代码上可以看出前提是对象(当然了,基本数据类型虽然也不会报错)3、for...in(只循环第一层)

    这里只提供下for...in的方法代码

     1 function simpleCopy(obj1) {
     2       var obj2 = Array.isArray(obj1) ? [] : {};
     3       for (let i in obj1) {
     4         obj2[i] = obj1[i];
     5       }
     6       return obj2;
     7     }
     8     var obj1 = {
     9       a: 1,
    10       b: 2,
    11       c: {
    12         d: 3
    13       }
    14     };
    15     var obj2 = simpleCopy(obj1);
    16     obj2.a = 3;
    17     obj2.c.d = 4;
    18     console.log(obj1);
    19     console.log(obj2);

    深拷贝方法:

    1、使用JSON.parse(JSON.stringify())

    1     var video = {
    2       like: 100
    3     };
    4     var copy = JSON.parse(JSON.stringify(video));
    5     copy.like = 10000;
    6     console.log(video);
    7     console.log(copy);

    缺点:它是不可以拷贝 undefined , function, RegExp 等等类型的

    2、递归拷贝,封装一个函数(推荐)

     1  let obj1 = {
     2         a: {
     3             c: /a/,
     4             d: undefined,
     5             b: null
     6         },
     7         b: function () {
     8             console.log(this.a)
     9         },
    10         c: [
    11             {
    12                 a: 'c',
    13                 b: /b/,
    14                 c: undefined
    15             },
    16             'a',
    17             3
    18         ]
    19     }
    20     let obj2 = deepClone(obj1);
    21     console.log(obj1);
    22     console.log(obj2);

    封装的深拷贝函数如下:

     1 // 定义一个深拷贝函数  接收目标target参数
     2     function deepClone(target) {
     3       // 定义一个变量
     4       let result;
     5       // 如果当前需要深拷贝的是一个对象的话
     6       if (typeof target === "object") {
     7         // 如果是一个数组的话
     8         if (Array.isArray(target)) {
     9           result = []; // 将result赋值为一个数组,并且执行遍历
    10           for (let i in target) {
    11             // 递归克隆数组中的每一项
    12             result.push(deepClone(target[i]));
    13           }
    14           // 判断如果当前的值是null的话;直接赋值为null
    15         } else if (target === null) {
    16           result = null;
    17           // 判断如果当前的值是一个RegExp对象的话,直接赋值
    18         } else if (target.constructor === RegExp) {
    19           result = target;
    20         } else {
    21           // 否则是普通对象,直接for in循环,递归赋值对象的所有值
    22           result = {};
    23           for (let i in target) {
    24             result[i] = deepClone(target[i]);
    25           }
    26         }
    27         // 如果不是对象的话,就是基本数据类型,那么直接赋值
    28       } else {
    29         result = target;
    30       }
    31       // 返回最终结果
    32       return result;
    33     }
  • 相关阅读:
    软件设计7个原则
    vue.js 样式绑定 font-size 问题
    实例理解scala 隐式转换(隐式值,隐式方法,隐式类)
    著名端口整理(常用服务的默认端总结)
    .NET Core Web API 实现大文件分片上传
    ngnix反向代理tomcat,ssl证书配置及自定义错误页面
    微信登录闪退
    gradle如何配置阿里云的中央仓库
    HashMap底层实现和原理
    关于Java中String类的hashCode方法
  • 原文地址:https://www.cnblogs.com/heisetianshi/p/15890180.html
Copyright © 2020-2023  润新知