• 浅拷贝与深拷贝


    浅拷贝和深拷贝都是对于JS中的引用类型而言的,浅拷贝就只是复制对象的引用(堆和栈的关系,简单类型undefined、null、boolean、number、string是存入堆,直接引用,object array则是存入栈中,只用一个指针来引用值),如果拷贝后的对象发生变化,原对象也会发生变化。只有深拷贝才是真正的对对象的拷贝。

      1)浅拷贝:就是只复制引用(指针),而未复制真正的值。

      2)深拷贝:就是对目标的完全拷贝,不像浅拷贝那样只是复制了一层引用,就连值也都复制了。只要进行了深拷贝,它们老死不相往来,谁也不会影响谁。

      实现方式:

      【1】利用JSON对象中的parse和stringify(undefined、function、symbol在转换过程中会丢失)

      【2】利用递归来实现每一层都重新创建对象并赋值

    function deepClone(source) {
                const targetObj = source.constructor === Array ? [] : {};
                for (let keys in source) {
                    if (source.hasOwnProperty(keys)) {
                        if (source[keys] && typeof source[keys] === 'object') {
                            targetObj[keys] = source[keys].constructor === Array ? [] : {};
                            targetObj[keys] = deepClone(source[keys]);
                        } else {
                            targetObj[keys] = source[keys];
                        }
                    }
                }
                return targetObj;
            }

      3)我们知道在JavaScript中,数组有两个方法concat和slice是可以实现对原数组的拷贝的,这两个方法都不会修改原数组,而是返回一个修改后的新数组。同时,ES6中引入了Object.assign方法和...展开云算法也能实现对对象的拷贝。

      Object.assign()是浅拷贝。

      concat、slice都只是对数组的第一层进行深拷贝。

      ...展开运算符,实现的是对象第一层的深拷贝。后面的只是拷贝的引用值。(首层浅拷贝)

      

      4)首层浅拷贝

    function shallowClone(source) {
                const targetObj = source.constructor === Array ? [] : {};
                for (let keys in source) {
                    if (source.hasOwnProperty(keys)) {
                        targetObj[keys] = source[keys];
                    }
                }
                return targetObj
            }
    

      

      5)总结:

      【1】赋值运算符 = 实现的是浅拷贝,只拷贝对象的引用值。

      【2】Javascript中数组和对象自带的拷贝方法都是“首层浅拷贝”

      【3】JSON.stringify实现的是深拷贝,但是对目标要求有要求(非undefined、function)

      【4】若想真正意义上的深拷贝,请递归。

      

      转载:http://www.cnblogs.com/dabingqi/p/8502932.html

      

  • 相关阅读:
    所谓的飞扬档案管理软件
    通过实例学习Virtools脚本语言VSL 解析字符串
    SQLite FAQ中文版
    通过实例学习Virtools脚本语言VSL 将物体排列于圆周上
    通过实例学习Virtools脚本语言VSL 解二次方程
    out 和 ref
    ASP.NET MVC深度接触:ASP.NET MVC请求生命周期
    ICSharpCode.SharpZipLib 压缩
    aspnet_regiis.exe 详解
    ASP.NET 配置文件 configSource 的用法
  • 原文地址:https://www.cnblogs.com/huen2015/p/10538616.html
Copyright © 2020-2023  润新知