zoukankan      html  css  js  c++  java
  • js 中的深拷贝和浅拷贝

     Shallow copy && Deep copy

     
    对于字符串类型,浅复制是对值的复制,对于对象来说,浅复制是对对象地址的复制,并没 有开辟新的栈,也就是复制的结果是两个对象指向同一个地址,修改其中一个对象的属性,则另一个对象的属性也会改变,
    举个栗子
    var arr = [1,2,3];
    var arrCopy = arr;
    arrCopy[0] = 100;   // 修改新数组的第0个值;
    arr[0]===arrCopy[0];  //true  原来的数组四不四也变了 
     而很多数情况下我们需要的是 新得到的对象与原来的对象互不相干,于是乎:

     深复制则是开辟新的栈,两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。我们来看看以下方法。

    Array 的 slice 和 concat 方法

    //slice
    var a = [1,2,3];
    var b = a.slice(); 
    b === a; // false
    
    //concat
    var a = [1,2,3];
    var b = a.concat(); 
    b === a;  // false
    
    你可能会说你看他们没有指向同一个地址啊,喵的肯定是 deep copy,表捉急。请看下面:
    
    var a = [[1,2,3],4,5];
    var b = a.slice();
    a[0][0]===b[0][0]; // true 
    
    true 了我去,第二层的复制明显不是 deep copy 啊。

    jQuery ——  $.extend()

    我们可以通过 $.extend() 方法来完成  深浅复制。这个方法可以传入一个参数:deep(true or false),表示是否执行深复制(如果是深复制则会执行递归复制)。

    var x = {
        a: 1,
        b: 2,
        c: {f:{g:1}}
    };
    
    var y = $.extend({}, x),          //浅 copy
        z = $.extend(true, {}, x);    //深 copy
    
    y.c.f === x.c.f       // true
    z.c.f === x.c.f       // false    $.extend 的用法很有意思,不单单只是 深浅copy, 有兴趣的崽儿可以到这个同学这里看看,总结的挺好 https://segmentfault.com/a/1190000004082170

    借助 JSON 全局对象

    针对纯 JSON 数据对象的深复制,使用 JSON 全局对象的 parse 和 stringify 方法来实现深复制也算是一个简单讨巧的方法。

    JOSN 对象中的 stringify 可以把一个 js 对象序列化为一个 JSON 字符串,parse 可以把 JSON 字符串反序列化为一个 js 对象,这两个方法实现的是深拷贝。然而使用这种方法会有一些隐藏的坑,

    它能正确处理的对象只有 Number, String, Boolean, Array, 扁平对象(function 就歇菜了,原型链也没了),即那些能够被 json 直接表示的数据结构。

    
    
    var arr = [0,1,2];
    var arrCopy =  JSON.parse(JSON.stringify(arr));
    arrCopy[0] = 333;
    
    arr[0]===arrCopy[0];  // false
    did u see that, 互不干扰,和谐盛世。

    总结下:

    Array 的 slice 和 concat 方法 和 jQuery 中的 extend 复制方法,他们都会复制第一层的值,对于 第一层 的值都是 深拷贝,

    而到 第二层 的时候 Array 的 slice 和 concat 方法就是 复制引用 ,jQuery 中的 extend 复制方法 则 取决于 你的 第一个参数, 也就是是否进行递归复制。

    而  JSON.parse(JSON.stringify(arr)) 在排除 被复制对象的 function 和原型链 之外,就是完全的复制啦 。

    今天,就酱紫。88了。

  • 相关阅读:
    2017年10月9日 冒泡&去重复习
    2017 年9月29日 弹出层特效
    2017 年9月28日 三级联动
    2017 年 9 月 27 日 js(文本框内容添加到select)
    2017 年 9 月 27 日 js(1.两个select 内容互换 2.单选按钮 同意可点击下一步 3. 全选框)
    2017 年 9 月26 日
    linux运维的认知及RHEL7 Unix/Linux 系统 介绍和安装
    Zabbix配置文件详解之服务端zabbix_server
    LoadRunner安装+汉化+破解
    zabbix告警“Zabbix poller processes more than 75% busy”
  • 原文地址:https://www.cnblogs.com/guoyu234/p/7383232.html
Copyright © 2011-2022 走看看