对象克隆

164 阅读2分钟

1.对象克隆

Object(Array)属于引用数据类型。当我们申明一个基本类型并对它进行赋值的时候,计算机会将值保存在栈内存中。而当我们申明一个引用数据类型并对它进行赋值的时候,计算机会将值保存在堆内存中,引用类型变量其实就是一个指针指向堆内存中。如果复制两相同的引用类型变量,其实它们最终指向同一个对象或者说堆内存空间
在js中,我们经常复制一个对象,复制数据,那么就会有人问了,怎么复制
JS中对象分为基本类型和复合(引用)类型,基本类型存放在栈内存,复合(引用)类型存放在堆内存。 堆内存用于存放由new创建的对象,栈内存存放一些基本类型的变量和对象的引用变量。

1.浅拷贝

浅克隆之所以被称为浅克隆,是因为对象只会被克隆最外部的一层,至于更深层的对象,则依然是通过引用指向同一块堆内存.所谓的浅复制,只是拷贝了基本类型的数据,而引用类型数据,复制后也是会发生引用,我们把这种拷贝叫做“(浅复制)浅拷贝”。

var obj1 = {
name: 'shen'
}
var obj2 = obj1
obj2.name = 'shenzhiyong'

console.log('obj1:', obj1)   // obj1: {name: "shenzhiyong"}
console.log('obj2:', obj2)   // obj2: {name: "shenzhiyong"}

var arr1 = [1,2,3]
var arr2 = arr1
arr2.push(4)
console.log('arr1:', arr1)   // arr1: [1,2,3,4]
console.log('arr2:', arr2)   // arr2: [1,2,3,4]

浅拷贝的意思就是只复制引用,没有复制真正的值。有时候我们只是想保留对象的数据,单纯想改变obj2和arr2的值,但是原对象的数据也发生了改变。很多时候这种情况都不是我们想要的。为了解决这个问题: 深拷贝它来了!

2.深拷贝

而深复制的话,我们要求复制一个复杂的对象,那么我们就可以利用递归的思想来做,及省性能,又不会发生引用。

  1. 函数不能拷贝
  2. Symbol不能拷贝
  3. undefined不能拷贝
  4. 正则拷贝后变成普通对象
  5. 循环引用的对象会报错
  6. 数组的属性丢失
    7. 数组里面的undefined会变成null
  7. 会抛弃对象的constructor
JSON方法
var obj1 = {
    name: 'shen'
}
var obj2 = JSON.parse(JSON.stringify(obj1))
obj2.name = 'shenzhiyong'

console.log('obj1:', obj1)   // obj1: {name: "shen"}
console.log('obj2:', obj2)   // obj2: {name: "shenzhiyong"}

优点:简单明了,方便记忆

缺点:看下面代码。当对象里面出现函数的时候就不适用了。

var obj1 = {
    name: 'shen',
    show: function (argument) {
        console.log(1)
    }
}
var obj2 = JSON.parse(JSON.stringify(obj1))
console.log('obj1:', obj1)  // obj1: {name: "shen", show: ƒ}
console.log('obj2:', obj2)  // obj2: {name: "shen"}