zoukankan      html  css  js  c++  java
  • JavaScript 之 深拷贝

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

     var obj={
                a:1,
                b:2,
                c:undefined,
                d:function(){
                    console.log("ddd")
                },
            }
            console.log("obj----------------",obj)
            let obj2=JSON.parse(JSON.stringify(obj))
            console.log("obj2---------------",obj2)

       这种方式不可以拷贝 undefined , function, RegExp 等等类型的,原理就是数据类型发生变化后 就和原数据无关了,数据类型变化本身就是在深拷贝了。

    2.使用Object.assign(target, source);

            var obj={
                a:1,
                b:2,
                c:[1,2,3,4]
            }
            var obj2 = Object.assign({},obj)
            console.log("obj------------",obj)
            obj2.c[0]=99
            console.log("obj2-----------",obj2)
    

     

    这种方式如果对象的属性对应的是其它的引用类型的话,还是只拷贝了引用,修改的话还是会有问题,Object.assign方法用来将源对象 “obj” 的所有可枚举属性,复制到目标对象"{}"。它至少需要两个对象作为参数,第一个参数是目标对象,后面的参数都是源对象。简单的来说就是把第二个对象里面的数据,拷贝到第一个空对象里面。

    3.使用 递归拷贝

            // 定义一个深拷贝函数  接收目标target参数
            function deepClone(target) {
                let result;            // 定义一个变量
                if (typeof target === 'object') {             // 如果当前需要深拷贝的是一个对象的话
                    if (Array.isArray(target)) {             // 如果是一个数组的话
                        result = []; // 将result赋值为一个数组,并且执行遍历
                        for (let i in target) {                      // 递归克隆数组中的每一项
                            result.push(deepClone(target[i]))
                        }
    
                    } else if(target===null) {               // 判断如果当前的值是null的话;直接赋值为null
                        result = null; 
                    } else if(target.constructor===RegExp){              // 判断如果当前的值是一个RegExp对象的话,直接赋值   
                        result = target;
                    }else {                 // 否则是普通对象,直接for in循环,递归赋值对象的所有值
                        result = {};
                        for (let i in target) {
                            result[i] = deepClone(target[i]);
                        }
                    }
                } else {              // 如果不是对象的话,就是基本数据类型,那么直接赋值
                    result = target;
                }
                return result;            // 返回最终结果
            }
            var obj={
                a:1,
                b:null,
                c:function(){
                    console.log("cccc")
                },
                d:/d/
            }
            var obj2=deepClone(obj)
            obj2.b={
                b1:111
            }
            obj2.a=undefined
            obj2.c=function(){
                console.log("这是新的CCCCC")
            }
            console.log("obj--------------",obj)
            console.log("obj2-------------",obj2)
            console.log("obj.c()----------",obj.c)
            console.log("obj2.c()---------",obj2.c)
    

    可以看到最终拷贝的结果是null、undefinde、function、RegExp等特殊的值也全部拷贝成功了,而且我们修改里边的值也不会有任何问题的

  • 相关阅读:
    spring cloud/spring boot同时支持http和https访问
    解决to the cache because there was insufficient free space available after evict
    国外天气api 国际天气预报今天、未来3天、未来7天的天气预报信息接口
    java 访问get接口请求外部的json数据
    IDEA创建基于Maven的SpringBoot项目-多模块
    PostgreSQL提取每个ID的最后一行(Postgresql extract last row for each id)
    Vue项目引入百度地图
    Vue 引入天地图 & 地图类型切换
    js在新窗口打开链接
    mysql使用小数注意
  • 原文地址:https://www.cnblogs.com/banyuege/p/14742615.html
Copyright © 2011-2022 走看看