深拷贝和浅拷贝

1. 引用类型那么它是如何在内存中保存它的值呢?(对象是引用类型下面以对象举例子)

    var obj1 = new Object();
    var obj2 = obj1;
    obj1.name = "Nicholas";
    alert(obj2.name);  //"Nicholas"
关于直接用等号复制内存解析
  • obj1 创建实例时在栈内存中开辟新空间以键值对形式保存,而这个值就是指针,指向堆内存的一个对象

  • obj2 = obj1 栈内存中开辟新空间储存 obj2,它的值跟obj1一样也是指针,均指向堆内存中的同一个对象

  • 为obj1添加属性name, obj2也就拥有了这个属性

2. 那么什么是深拷贝什么是浅拷贝呢?

  • 第一次看到这个这个概念是在《ES6标准入门》中的 9.5.2 注意点
  • Object.assign() 这个方法实行的是浅拷贝
var obj1 = {
  'a': {
      'b': 1,
      'c': 2
   },
  'd': 3
};
var obj2 = Object.assign({}, obj1);

obj1.d =4;    // 通过 obj1改变 d
obj2.d;       //  输出 obj2.d 发现值为3并没有改变

obj1.a.b = 3;   // 通过 obj1改变 a 对象中 b 属性的值
obj2.a.b;       //  输出 obj2.a.b 发现值是3 不再 2
  • 解释: 上面有两种情况,改变对象第一层属性彼此不相互影响,而内嵌的对象b c 两个对象之间共享(把obj1 a 对象拷贝给obj2只是拷贝了a 的引用),这就是浅拷贝

  • 浅拷贝:将 B 对象拷贝到 A 对象中,但不包括 B 里面的子对象

  • 深拷贝:将 B 对象拷贝到 A 对象中,但包括 B 里面的子对象

3. 无子对象的深拷贝(比如数组里装的都是基本类型)

var arr1 = [1,2,3,4];
var arr2 = arr1.slice(0); // 实现深拷贝
arr2.pop();
arr1 // [1,2,3,4]
arr2 // [1,2,3]

4. 有子对象的深拷贝

  • Using JSON.parse(JSON.stringify(object));
let obj = { 
  a: 1,
  b: { 
    c: 2,
  },
}
let newObj = JSON.parse(JSON.stringify(obj));
obj.b.c = 20;
console.log(obj); // { a: 1, b: { c: 20 } }
console.log(newObj); // { a: 1, b: { c: 2 } } (New Object Intact!)
  • 另一种
function cloneObject(obj) {
    var clone = {};
    for(var i in obj) {
        if(obj[i] != null &&  typeof(obj[i])=="object")
            clone[i] = cloneObject(obj[i]);
        else
            clone[i] = obj[i];
    }
    return clone;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容