https://www.cnblogs.com/chengxs/p/10788442.html
var arr = [true,1,'str',{ a: 1}] console.log(arr) //[true, 1, "str", {…}] var a = JSON.parse(JSON.stringify(arr)) console.log(a) //[true, 1, "str", {…}] a.splice(0,2) console.log(a) //["str", {…}] console.log(arr) //[true, 1, "str", {…}] var ar = arr console.log(ar) //[true, 1, "str", {…}] ar.splice(0,1) console.log(ar) //[1, "str", {…}] console.log(arr) //[1, "str", {…}]
什么是深拷贝
使用json.parse(json.stringify())是深拷贝
原理是JOSN对象中的stringify可以把一个js对象序列化为一个JSON字符串,parse可以把JSON字符串反序列化为一个js对象,通过这两个方法,也可以实现对象的深复制。但是这个方法不能够拷贝函数。
缺点:
(1)如果对象里有函数,函数无法被拷贝下来
(2)无法拷贝copyObj对象原型链上的属性和方法
(3)当数据的层次很深,会栈溢出
其他深拷贝的方法
function fn(obj) { if(typeof obj !== 'object' || obj === null) return var newObj = obj instanceof Array ? []:{} for(var key in obj) { if(obj.hasOwnProperty(key)){ if(typeof obj[key] === 'object'){ newObj[key] = fn(obj[key]) }//如果检测某一项是一个对象,就递归调用方法进行深拷贝 else{ newObj[key]=obj[key] } } } return newObj }
缺点:
(1)无法保持引用
(2)当数据的层次很深,会栈溢出
浅拷贝:
什么是浅拷贝
创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
(简单来说就是如果原始对象属性值是基本类型不是引用类型,原对象和新对象无论谁做修改都不会影响彼此,但是如果原始对象属性值存在引用类型,在新对象对引用类型进行修改的时候,会影响老对象的引用类型)
1.第一种方法
function fn(obj) { if(typeof obj !== 'object' || obj === null) return var newObj = obj instanceof Array ? []:{} for(var key in obj) { if(obj.hasOwnProperty(key)){ newObj[key]=obj[key] } } return newObj }
2.第二种方法Object.assign()
方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
let a = {}
let b = Object.assign({}, a);
将a对象的可枚举属性复制到了一个空对象,然后返回目标对象赋值给b实现了浅拷贝
3.第三种方法
展开运算符...
let a = {}
let b = {...a} 实现了浅拷贝
4.第四种方法
使用Array.from来复制一个数组,复制后的数组是浅拷贝
let a = [] , let b =Array.from(a);