js浅拷贝和深拷贝

浅拷贝是拷贝一层,深层次的对象级别的就拷贝引用;深拷贝是拷贝多层,每一级别的数据都会拷贝出来;

理解:浅拷贝的时候如果数据是基本数据类型,那么就如同直接赋值那种,会拷贝其本身;

如果除了基本数据类型之外还有一层对象,那么对于浅拷贝而言就只能拷贝其引用,对象的改变会反应到拷贝对象上;

但是深拷贝就会拷贝多层,即使是嵌套了对象,也会都拷贝出来。

即浅拷贝只拷贝第一层的数据,开辟新的内存空间,下面的层次还是共用内存空间;

而深拷贝每一层都是新的内存空间,独立起来的

浅拷贝的常用方法:

1.ES6的扩展运算符

let obj = {
name:“dilireba”
}
let newObj = {…obj}
obj.name = “liqin”
console.log(obj,newObj)
//{ name: ‘liqin’ } { name: ‘dilireba’ }

2.ES6中的Object.assign方法

var obj1 = {
    a: "hello",
    b: {
        a: "hello",
        b: 21}
};
 
var cloneObj1= Object.assign({}, obj1);
cloneObj1.a = "changed"; 
cloneObj1.b.a = "changed";
console.log(obj1.a);  //hello
console.log(obj.b.a); // "changed"

改变cloneObj1.a的时候,因为是浅拷贝在第一层,互不影响,所以obj1.a还是hello

改变cloneObj1.b.a的时候,是在第二层的,与obj1.b.a共用一个内存空间,所以obj1.b.a是新的数据changed

深拷贝常用方法:

1.转成 JSON 再转回来

JSON.parse(JSON.stringify(obj))

缺点:

抛弃对象的constructor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object。

只有可以转成JSON格式的对象才可以这样用,像function没办法转成JSON,

如果你拷贝的对象中存在函数,函数会消失

var obj1 = { fun: function(){ console.log(123) } };
var obj2 = JSON.parse(JSON.stringify(obj1));
console.log(typeof obj1.fun);
// 'function'
console.log(typeof obj2.fun);
// 'undefined' <-- 没复制

2.递归拷贝

function deepClone(initalObj, finalObj) {    
  var obj = finalObj || {};    
  for (var i in initalObj) {        
    var prop = initalObj[i];        // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
    if(prop === obj) {            
      continue;
    }        
    if (typeof prop === 'object') {
      obj[i] = (prop.constructor === Array) ? [] : {};            
      arguments.callee(prop, obj[i]);
    } else {
      obj[i] = prop;
    }
  }    
  return obj;
}
var str = {};
var obj = { a: {a: "hello", b: 21} };
deepClone(obj, str);
console.log(str.a);

 

posted on 2020-07-01 14:31  sss大辉  阅读(186)  评论(0编辑  收藏  举报

导航