深浅拷贝
如果一个json直接做等于赋值 当你c改变b属性的值时 a中的b也会变化
var a = {
b :'1'
}
var c = b
c.b = 2;
而浅拷贝是 如果你a对象中里面都是基本类型的话 改变b属性的值 a不会跟着变化
如果是a.b是一个对象的话 你改变c.b中的值a里面的b仍然会变化
深拷贝就是 a 跟 c 对象已经无关了 无论你怎么去改c 都不会影响到a对象
浅拷贝:只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存
深拷贝:会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
为什么会 出现这种情况
在内存中的存储方式不同,原始数据类型在内存中是堆存储,引用类型是栈存储 栈(stack)为自动分配的内存空间,它由系统自动释放;而堆(heap)则是动态分配的内存,大小不定也不会自动释放。在内存中存储方式的不同导致了原始数据类型不可变 原始数据类型和引用数据类型做赋值操作一个是传值一个是传址
为什么会 出现这种情况
在内存中的存储方式不同,原始数据类型在内存中是堆存储,引用类型是栈存储 栈(stack)为自动分配的内存空间,它由系统自动释放;而堆(heap)则是动态分配的内存,大小不定也不会自动释放。在内存中存储方式的不同导致了原始数据类型不可变 原始数据类型和引用数据类型做赋值操作一个是传值一个是传址
浅拷贝
1.object.assign()
Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
var arr = [1, [7, [9]], {a:'1'}, function(){}, null, undefined, NaN]; var result= Object.assign(arr); arr[2][a]='222'; console.log(arr); //output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN]; console.log(result); //output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN];
2.拓展运算符…
var arr = [1, [7, [9]], {a:'1'}, function(){}, null, undefined, NaN]; var result= [...arr]; arr[2][a]='222'; console.log(arr); //output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN]; console.log(result); //output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN];
深拷贝
1.JSON.parse(JSON.stringify(arr));
var arr = [1, [7, [9]], {a:'1'}, function(){}, null, undefined, NaN]; var result = JSON.parse(JSON.stringify(arr));arr[2][a]='222'; console.log(arr); //output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN]; console.log(result); //output: [1, [7,[9]], {a:'111'}, null, null, null, null]
JSON.parse(JSON.stringify(obj))深拷贝的问题
1、如果obj里面存在时间对象,JSON.parse(JSON.stringify(obj))之后,时间对象变成了字符串。
2、如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象。
3、如果obj里有函数,undefined,则序列化的结果会把函数, undefined丢失。
4、如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null。
5、JSON.stringify()只能序列化对象的可枚举的自有属性。如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor。
6、如果对象中存在循环引用的情况也无法正确实现深拷贝
2.递归遍历
var arr = [1, [7, [9]], { a: '1'}, function () {}, null, undefined, NaN]; function deepCopy(arr) { if (typeof obj !== 'object') return; var newObj = obj instanceof Array ? [] : {}; for (var key in obj) { if (obj.hasOwnProperty(key)) { if(obj[key]===null){newObj[key]=null;continue;} newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]; } } return newObj; } var result = deepCopy(arr)); arr[2][a]='222'; console.log(arr); //output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN]; console.log(result); //output: [1, [7, [9]], { a: '1'}, function () {}, null, undefined, NaN]
JSON.parse(JSON.stringify(obj))比递归遍历慢一倍
JSON.parse(JSON.stringify(obj)) 每个对象处理时间 * 2 (递归转字符串 + 递归解析)
递归遍历: 每个对象处理时间