浅拷贝是指只复制一层对象,当对象的属性是引用类型时,实质复制的是其引用,当引用指向的值改变时也会跟着变化;
深拷贝是指复制对象的所有层级。
1. 浅拷贝
浅拷贝的方法: Object.assign
let obj = {a: 1, b: {title: 'hello', name: 'John'}} let obj1 = Object.assign({}, obj) obj.a = 2 obj.b.name = 'Smith' console.log(obj1.a, obj1.b.name) // 1 Smith
可见,obj的a属性改变时,不影响obj1中a的改变;但引用类型,b中属性值的改变会同步到obj1。
实现浅拷贝的方法还可以使用 ...展开运算符
1 let obj = {a: 1, b: {title: 'hello', name: 'John'}} 2 let obj1 = {...obj} 3 obj.a = 2 4 obj.b.name = 'Smith' 5 console.log(obj1.a, obj1.b.name) // 1 Smith
我们可以手动实现一个简单的浅拷贝函数,如下:
1 function closeShallow(source) { 2 var target = Object.create(null) 3 for (let key in source) { 4 if (Object.prototype.hasOwnProperty.call(source, key)) { 5 target[key] = source[key] 6 } 7 } 8 return target 9 } 10 let obj = {a: 1, b: {title: 'hello', name: 'John'}} 11 let obj1 = closeShallow(obj) 12 obj.a = 2 13 obj.b.name = 'Smith' 14 console.log(obj1.a, obj1.b.name) // 1 Smith
2. 深拷贝
深拷贝的方法JSON.parse(JSON.stringify())
1 let obj = {a: 1, b: {title: 'hello', name: 'John'}} 2 let obj1 = JSON.parse(JSON.stringify(obj)) 3 obj.a = 2 4 obj.b.name = 'Smith' 5 console.log(obj1.a, obj1.b.name) // 1 John
也以使用lodash的cloneDeep方法来实现
手动实现深拷贝实际上是在浅拷贝的基础上使用递归调用,代码如下:
function cloneDeep(source) { var target = Object.create(null) for (let key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { if (typeof source[key] === 'object') { target[key] = cloneDeep(source[key]) } else { target[key] = source[key] } } } return target } let obj = {a: 1, b: {title: 'hello', name: 'John'}} let obj1 = cloneDeep(obj) obj.a = 2 obj.b.name = 'Smith' console.log(obj1.a, obj1.b.name) // 1 John