浅析---浅拷贝与深拷贝

          拷贝(也称克隆),指的是我们对从服务器请求回来的数据,进行"复制",我们可以对副本进行修改等操作,不能影响到原来的数据,如果修改的数据不理想,可以在不向服务器从新发送请求的情况下,返回到原来的数据,

          浅拷贝和深拷贝的区别是:浅拷贝只会拷贝对象最外部的一层,至于更深层次的对象,则依然是通过引用指向同一块堆内存.(意思是,拷贝之后的对象发生了变化,原对象也会发生变化);而深拷贝在一定程度上,解决了这个问题


浅拷贝

        // 浅拷贝函数

            function shallowClone(oldobj) {

                  const obj = { };   //const 常量

                  for ( let   i   in  obj) {

                        obj [i] = oldobj [i];

                  }

                  return obj;

            }

        // 被克隆对象

        const oldObj = {

                  a: 1,

                  b: [ 'e', 'f', 'g' ],

                  c: { h: { i: 2 } }

         };

        const newObj = shallowClone(oldObj);

        console.log(newObj.c.h, oldObj.c.h);     // { i: 2 } { i: 2 }  

        console.log(oldObj.c.h === newObj.c.h);    // true

        newObj.c.h.i = 'change';

        console.log(newObj.c.h, oldObj.c.h);   // { i: 'change' } { i: 'change' }

        // 改变newobj的值,oldobj的值也会变(说明他们指向了同一段堆内存),这种效果并不是我们想要的,所以,出现了深拷贝

深拷贝

    第一种方法--------深拷贝函数

```

//使用递归的方式实现数组、对象的深拷贝

function deepClone1(obj) {

  //判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝

  var objClone = Array.isArray(obj) ? [] : {};

  //进行深拷贝的不能为空,并且是对象或者是

  if (obj && typeof obj === "object") {

    for (key in obj) {

      if (obj.hasOwnProperty(key)) {

        if (obj[key] && typeof obj[key] === "object") {

          objClone[key] = deepClone1(obj[key]);

        } else {

          objClone[key] = obj[key];

        }

      }

    }

  }

  return objClone;

原文链接:https://blog.csdn.net/chentony123/article/details/81428803

```

                var oldobj={

                    name:"apple",

                    price:28,

                    des:{a:{i:3}}

                }

                    var  newobj = deepCopy(oldobj);

                    console.log(newobj,oldobj);  // { i : 3 },{ i : 3 }

                    newobj.des.a.i=7;

                    console.log(newobj,oldobj);// { i : 7 },{ i : 3 }     //新对象的 i 值变了,原对象的 i 值并没有变

第二种方法------json.parse(),和json.stringify()方法

             var oldobj={

                    name:"apple",

                    price:28,

                    des:{a:{i:3}}

                }

                var  newobj = JSON.parse(JSON.stringify(oldobj));

                console.log(newobj,oldobj);  // { i : 3 },{ i : 3 }

                 newobj.des.a.i=7; 

                 console.log(newobj,oldobj);// { i : 7 },{ i : 3 }     //得到的效果是和深拷贝函数的效果一样

但是,深拷贝的两种方法,都只能解决普通的深拷贝问题,特殊的对象(函数,正则对象,构造函数,稀疏数组),这两种方法还解决不了.

            functionPerson(name){

                    this.name=name;

            }

          var lili= new Person("lili")

            function say(){

                    console.log("hi")

            }

            var oldobj= {

                    a:lili,

                    b:say,

                    c:new Array(1),

                    d:RegExp("abc","i")

            }

        var newobj= deepcopy(oldobj);

        console.log(newobj.a,oldobj.a);      //object   , Person  //构造函数的指向不一样

        console.log(newobj.b,oldobj.b);      //function , function  拷贝函数打印的效果是对的,json.parse方法不行,打印的新对象为空

        console.log(newobj.c,oldobj.c);      // {  }, [ empty ]

        console.log(newobj.d,oldobj.d);     // {  },  / abc / i


总结:一般情况下,深拷贝的两种方法就应经够用了,如果遇到处理特殊对象的问题,再具体问题具体分析吧.


```

// 深克隆

// 循环遍历每一个元素,判断是原始值还是引用值

// 如果是原始值,就直接赋值,如果是引用值,就再次判断是object,还是array

// 新建 [] || {} 再赋值

// 循环递归

function deepclone (orign,target){

var target = target || {}

var toStr = Object.prototype.toString

for(var prop in orign){

if(orign.hasOwnProperty(prop)){

if(typeof(orign[prop]) == 'object' && typeof(orign[prop])== null){

if(toStr.call(orign[prop]) === '[Object Array]'){

target[prop] = []

} else {

target[prop] = {}

}

deepclone(orign[prop],target[prop])

}else {

target[prop] = orign[prop]

}

}

}

return target

}

```

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,057评论 0 13
  • 单例模式 适用场景:可能会在场景中使用到对象,但只有一个实例,加载时并不主动创建,需要时才创建 最常见的单例模式,...
    Obeing阅读 2,017评论 1 10
  • 《ijs》速成开发手册3.0 官方用户交流:iApp开发交流(1) 239547050iApp开发交流(2) 10...
    叶染柒丶阅读 4,740评论 0 7
  • title: 原生js对象的浅拷贝和深拷贝的总结 这里是说明. 在此之前我们先复习两个知识点. 第一个知识点:对象...
    KingJeason阅读 805评论 1 8
  • 有这么一个人,于星星而言,看似遥不可及,却又触手可及。 遇见你的时候所有星星都落到我头上 第一次知道张杰这个名字,...
    小巨人啊_阅读 1,357评论 3 1