浅拷贝:比如拷贝A对象,浅拷贝就是从内存中开辟出新的一块内存创建一个空对象,该空对象的引用是从A对象那里拷贝过来的,都指向A对象,若有若干个浅拷贝则多个空对象指向A对象,任何一个对象修改值所有对象中的数据 都会被修改,因为大家共用数据。
深拷贝:深拷贝不会拷贝引用类型的引用,而是将引用类型的值全部拷贝一份,形成一个新的引用类型,修改拷贝被拷贝对象中的值互不影响干扰。
JS中实现深拷贝有三种方法:利用json、利用Object.assin()、利用递归
1.利用json
var obj = {
name: 'jack',
age: 18
}
function deepCopy(obj) {
var jsonString = JSON.stringify(obj)//将被拷贝的对象转换为json字符串
var jsonObj = JSON.parse(jsonString)//将待拷贝对象转换为新的JS对象
return jsonObj
}
var oldObj1 = obj //浅拷贝
var oldObj2 = deepCopy(obj) //深拷贝
obj.name = 'lucy'
console.log(oldObj1.name);//lucy
console.log(oldObj2.name);//jack
2.利用递归
<script>
let obj = {
a: 1,
b: 2,
hobby: ['C', 'JS', 'C++'],
school: {
locationSchool: '南京',
name: '河海大学'
},
fn: function () {
console.log("函数被调用");
}
}
//只针对引用类型数据的深拷贝
function deepClone(source) {
//被拷贝数据是函数(Function类型)
if (source instanceof Function) {
const targetObj = source
return targetObj
} else {
//被拷贝数据是引用类型:数组[],对象{}
const targetObj = source instanceof Array ? [] : {}
for (let key in source) {
if (source.hasOwnProperty(key)) {
//若属性为引用类型,递归
if (source[key] && source[key] instanceof Object) {
targetObj[key] = deepClone(source[key])
} else {
//基本类型
targetObj[key] = source[key]
}
}
}
return targetObj
}
}
let newObj2 = deepClone(obj)
newObj2.hobby.push('JAVA')
console.log(obj.hobby);//['C', 'JS', 'C++']
console.log(newObj2.hobby);//['C', 'JS', 'C++', 'JAVA']
newObj2.school.name = '北大'
//递归方式解决了利用json实现深拷贝中JS关键字丢失的问题
newObj2.fn()//“函数被调用”
console.log(obj.school.name);//河海大学
console.log(newObj2.school.name);//北大
</script>