• js 数组对象深拷贝


    结论:对象的拷贝不能采用直接赋值的方式。

    背景

    踩过的坑如下:

    formData本来是父组件传过来的,但是我不想直接用,于是我直接赋值给一个formDataCopy的对象。

    但是诡异的事情发生了,就是在我填写自己的表单组件的时候,一旦表单的数据发生的变化时,本来是formDataCopy的值发生变化,但是‘formDataDefault值’ 这个字符串却被打印出来,也就是说formData改变了。

    奇怪,formData是父组件传过来的值怎么会改变呢?

    经过一番挣扎,才发现formDataCopy使用的是简单的赋值,导致formDataCopy和formData指向相同的对象。

    formDataCopy一改变,formData就会跟着变。

    以上是背景,所以我就对浅拷贝和深拷贝进行了总结:

    浅拷贝

    什么是浅拷贝:两者是指向一个对象。

    对象的浅拷贝

    1、对象的直接遍历赋值。

    2、ES6中的 var copyObj = Object.assign({}, obj);

    3、ES7扩展运算符 var copyObj = { ...obj }

    4、Jquery浅拷贝 var copiedObject = jQuery.extend({}, originalObject) 如果改变了originalObject,copiedObject 也会变。

    数组的浅拷贝

    (两者指向不同的对象,但是只能拷贝一层)

    • array.concat();
    • array.slice(0);

    如果该元素是个对象引用 (不是实际的对象),slice 会拷贝这个对象引用到新的数组里。两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变,所以是浅拷贝。

    对于字符串、数字及布尔值来说(不是 String、Number 或者 Boolean 对象),slice 会拷贝这些值到新的数组里。在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组。

    也就是说,如果原数组改变的是基本数据类型,比如String,Boolean,Number的数据,不会影响到新数组;
    但是如果改变的是对象或者数组中的数据,是会影响到新数组的,也也就是对于对象或者数组,新旧数组指向的是一个对象。

    深拷贝

    (下面说的深拷贝是基本对象的深拷贝,不考虑对象的复杂属性,比如set,get,Function等)

    1、最简单的方式 JSON.parse(JSON.stringify(Obj)) 这种方法使用较为简单,可以满足基本的深拷贝需求,而且能够处理JSON格式能表示的所有数据类型,但是对于正则表达式类型、函数类型等无法进行深拷贝(而且会直接丢失相应的值)。

    2、jQuery深拷贝 var copiedObject = $.extend(true, {}, originalObject)

    3、手动写递归方式

    var array = [
       { number: 1 },
       { number: 2 },
       { number: 3 }
    ];
    function copy (obj) {
            var newobj = obj.constructor === Array ? [] : {};
            if(typeof obj !== 'object'){
                return;
            }
            for(var i in obj){
               newobj[i] = typeof obj[i] === 'object' ? copy(obj[i]) : obj[i];
            }
            return newobj
    }
    var copyArray = copy(array)
    copyArray[0].number = 100;
    console.log(array); //  [{number: 1}, { number: 2 }, { number: 3 }]
    console.log(copyArray); // [{number: 100}, { number: 2 }, { number: 3 }]
    

    参考文档

    https://www.cnblogs.com/penghuwan/p/7359026.html

    https://github.com/wengjq/Blog/issues/3

  • 相关阅读:
    javascript 去掉 url 中的不可打印字符串
    双链表 哈希 go 实现lFU 缓存算法
    博客园嵌入背景音乐
    博客园嵌入B站视频教程
    基于C++二叉树链表实现同学录信息系统
    C++ 二叉树知识点
    datatable 自定义排序 及 多列排序
    jq 提取字符串中的数字
    wamp下thinkPHP3.2 系统不支持:redis 解决方法
    editable文档
  • 原文地址:https://www.cnblogs.com/lvonve/p/11334628.html
Copyright © 2020-2023  润新知