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.深拷贝
而深复制的话,我们要求复制一个复杂的对象,那么我们就可以利用递归的思想来做,及省性能,又不会发生引用。
- 函数不能拷贝
- Symbol不能拷贝
- undefined不能拷贝
- 正则拷贝后变成普通对象
- 循环引用的对象会报错
- 数组的属性丢失
7. 数组里面的undefined会变成null - 会抛弃对象的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"}