JavaScript中的深浅复制

作者: baiying | 来源:发表于2017-08-15 21:53 被阅读52次

什么是深浅复制

  • 浅复制:浅复制就是复制一份引用,所有的引用对象都指向同一份数据,并且都可以修改这份数据.
  • 深复制:所谓”深拷贝”,就是能够实现真正意义上的数组和对象的拷
var a = 5;
var b = a;
b = 1;
console.log(a);//5
console.log(b);//1
var a = {name:tom};
var b = a;
b.name = 'lisa';
console.log(a.name);//lisa
console.log(b.name);//lisa

由上述代码可见,基本类型的赋值是深复制,引用类型的赋值是浅复制

如何实现引用类型深复制

浅复制是非常简单的,那么对于引用类型来说要如何实现深复制呢

  • Object.assign()方法(一层深复制)
var obj = {name:'tom',age:10,like:{fruit:'apple'}};
var newObj = Object.assign({},obj);
console.log(newObj);
obj.name = 'lisa';
obj.like.fruit = 'peach';
console.log(newObj);
//第一个输出结果
{
  age: 10,
  like: [object Object] {
    fruit: "apple"
  },
  name: "tom"
}
//第二个输出结果
{
  age: 10,
  like: [object Object] {
    fruit: "peach"
  },
  name: "tom"
}

我们看到对象的第一层的属性值的修改并不会互相影响,也就是说他们占用的是不同的内存,但是第二层的属性值的修改却会互相影响,所以第二层复制过来得只是对象的引用,他们是指向同一块内存的
因此:Object.assign()方法只实现了对象第一层的深复制,更深层的都是浅复制.

  • JSON对象的json.stringify()方法和json.parse()方法
    • json.stringify():将js对象转换成字符串对象
    • json.parse():将字符串对象转换成js对象
var obj = {name:'tom',age:10,like:{fruit:'apple'}};
var strObj = JSON.stringify(obj);
var jsObj = JSON.parse(strObj);
obj.name = 'lisa';
obj.like.fruit = 'peach';
console.log(jsObj);
//输出结果
{
  age: 10,
  like: [object Object] {
    fruit: "apple"
  },
  name: "tom"
}

我们看到在obj上的修改都不会影响到最终的jsObj,所以结合这两个方法可以轻松实现对象的深复制.

  • 原生js实现深拷贝
    思路:如果对象属性值是基本类型则直接赋值(前边提过,基本类型的赋值属于深拷贝)如果对象是引用类型,则递归至基本类型再赋值
function deepCopy(p,c) {
   if(p === null || typeof p !== "object"){//非引用类型的深拷贝直接赋值
           return p;
       }
    var c = c || {};
    for (var i in p) {//引用类型,遍历属性
        if (typeof p[i] === 'object') { //属性值是引用类型
            c[i] = (p[i].constructor === Array) ? [] : {};//属性值是数组还是对象决定递归时传入的c[i]是[]还是{}
            deepCopy(p[i], c[i]);//递归拷贝
        } else {
            c[i] = p[i];//属性值是基本类型,直接赋值
        }
    }
    return c;
}

var target = {name:'tom',age:1,like:{fruit:['apple','peach']}};
var copyObj =  (deepCopy(target));
console.log(copyObj);
target.name = 'lisa';
target.like.fruit = ['apple'];
console.log(copyObj);
//第一次输出结果
 {
  age: 1,
  like: [object Object] {
    fruit: ["apple", "peach"]
  },
  name: "tom"
}
//第二次输出结果
 {
  age: 1,
  like: [object Object] {
    fruit: ["apple", "peach"]
  },
  name: "tom"
}

我们可以看到上述代码实现了对象的深拷贝,拷贝后两个对象的修改并不会相互影响.

相关文章

  • JavaScript中的深浅复制

    什么是深浅复制 浅复制:浅复制就是复制一份引用,所有的引用对象都指向同一份数据,并且都可以修改这份数据. 深复制:...

  • JavaScript的深浅复制

    为什么有深复制、浅复制?JavaScript中有两种数据类型,基本数据类型如undefined、null、bool...

  • JavaScript对象的深浅复制

    前言 从层次上来看,对象的复制可以简单地分为浅复制和深复制,顾名思义,浅复制是指只复制一层对象的属性,不会复制对象...

  • iOS中的深浅复制

    iOS中的深浅复制

  • JavaScript中的深浅拷贝

    深浅拷贝 从上面的例子可以发现,如果给一个变量赋值一个对象,那么两者的值会是同一个引用,其中一方改变,另一方也会相...

  • JavaScript 中的深浅拷贝

    从上面的例子可以发现,如果给一个变量赋值一个对象,那么两者的值会是同一个引用,其中一方改变,另一方也会相应改变。 ...

  • JS中的深浅复制

    什么是深浅复制? 深复制:把要复制的对象的所引用的全部对象都复制一遍。开辟新空间。 浅复制:仅仅复制对象的引用,而...

  • javascript设置网页无法复制

    javascript设置网页无法复制的方法:在JavaScript代码中设置禁用右键菜单、复制、选择等操作,禁用C...

  • Python的复制(拷贝)问题

    深浅复制的讨论是基于可变类型的 浅复制 复制最外层容器,副本中的元素是源容器中元素的引用 列表浅复制包括...

  • 深浅复制

    深浅复制和属性为copy,strong值的变化问题 浅复制:只复制指向对象的指针,而不复制引用对象本身。对于浅复制...

网友评论

    本文标题:JavaScript中的深浅复制

    本文链接:https://www.haomeiwen.com/subject/hksprxtx.html