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

    何为深拷贝和浅拷贝

              在 JS 中有一些基本类型像是NumberStringBoolean,而对象就是像这样的东西{ name: 'Larry', skill: 'Node.js' },对象跟基本类型最大的不同就在于他们的传值方式。

    基本类型是按值传递,像是这样:在修改a时并不会改到b。

    var a = 25;
    var b = a;
    b = 18;
    console.log(a);//25
    console.log(b);//18

    但对象就不同,对象传的是按引用传值

    var obj1 = { a: 10, b: 20, c: 30 };
    var obj2 = obj1;
    obj2.b = 100;
    console.log(obj1);
    // { a: 10, b: 100, c: 30 } <-- b 被改到了
    console.log(obj2);
    // { a: 10, b: 100, c: 30 }

    复制一份obj1叫做obj2,然后把obj2.b改成100,但却不小心改到obj1.b,因为他们根本是同一个对象,这就是所谓的浅拷贝。

    要避免这样的错误发生就要写成这样:

    var obj1 = { a: 10, b: 20, c: 30 };
    var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c };
    obj2.b = 100;
    console.log(obj1);
    // { a: 10, b: 20, c: 30 } <-- b 沒被改到
    console.log(obj2);
    // { a: 10, b: 100, c: 30 }

    这样就是深拷贝,不会改到原本的obj1。

     

    浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

    如何实现深拷贝

    浅拷贝的实现方式,也就是简单地复制而已,如何实现深拷贝呢?

    手动复制

    把一个对象的属性复制给另一个对象的属性

    var obj1 = { a: 10, b: 20, c: 30 };
    var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c };
    obj2.b = 100;
    console.log(obj1);
    // { a: 10, b: 20, c: 30 } <-- 沒被改到
    console.log(obj2);
    // { a: 10, b: 100, c: 30 }

    但这样很麻烦,要一个一个自己复制;而且这样的本质也不能算是 Deep Copy,因为对象里面也可能回事对象,如像下面这个状况:

    var obj1 = { body: { a: 10 } };
    var obj2 = { body: obj1.body };
    obj2.body.a = 20;
    console.log(obj1);
    // { body: { a: 20 } } <-- 被改到了
    console.log(obj2);
    // { body: { a: 20 } }
    console.log(obj1 === obj2);
    // false
    console.log(obj1.body === obj2.body);
    // true

    虽然obj1obj2是不同对象,但他们会共享同一个obj1.body所以修改obj2.body.a时也会修改到旧的。

    递归拷贝

    function deepClone(initalObj, finalObj) {    
      var obj = finalObj || {};    
      for (var i in initalObj) {        
        if (typeof initalObj[i] === 'object') {
          obj[i] = (initalObj[i].constructor === Array) ? [] : {};            
          arguments.callee(initalObj[i], obj[i]);
        } else {
          obj[i] = initalObj[i];
        }
      }    
      return obj;
    }
    var str = {};
    var obj = { a: {a: "hello", b: 21} };
    deepClone(obj, str);
    console.log(str.a);

    jquery

    jquery 有提供一个$.extend可以用来做 Deep Copy。

    var $ = require('jquery');
    var obj1 = {
        a: 1,
        b: { f: { g: 1 } },
        c: [1, 2, 3]
    };
    var obj2 = $.extend(true, {}, obj1);
    console.log(obj1.b.f === obj2.b.f);
    // false
  • 相关阅读:
    程序员数学
    [topcoder]FlowerGarden
    [leetcode]Trapping Rain Water
    [leetcode]Gray Code
    [leetcode]Unique Paths II
    hdu 4112 Break the Chocolate(ceil floor)
    【转】博弈-翻硬币游戏
    POJ 3710 Christmas Game
    hdu 3590 PP and QQ
    博弈进阶
  • 原文地址:https://www.cnblogs.com/qixinbo/p/7517389.html
Copyright © 2011-2022 走看看