浅拷贝:
基本数据类型
只是让栈内存的信息复制了一份,因为基本数据类型变量值和名称均在栈中所以其不存在深拷贝或浅拷贝问题 复制出的新对象与原对象之间互不影响
复杂数据类型
将栈内存的指针赋值一份,但是指针指向堆内存的同一对象,所以当新对象修改数据时原对象一样会受到影响
slice和concat这两个方法,可以实现对包含引用对象的一维数组的浅拷贝
深拷贝
即在栈内存复制出一份指针,堆内存中复制出另一份真正的对象
创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
. JSON.parse(JSON.stringify())
原理: 用JSON.stringify将对象转成JSON字符串,
再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,
而且对象会开辟新的栈,实现深拷贝。
这种方法虽然可以实现数组或对象深拷贝,但不能处理函数。
这是因为 JSON.stringify() 方法是将一个JavaScript值(对象或者数组)转换为一个 JSON字符串,不能接受函数。
例子:
<script>
var p = {
"id": "007",
"name": "刘德华",
"books": new Array("三国演义", "红楼梦", "水浒传"),//这是引用类型,
"wife": {
"id": "008",
"name": "刘德的妻子",
"address": {
"city": "北京",
"area": "海淀区"
}
}
}
function copyObj(obj) {
let newObj = {};
for (let key in obj) {
if (typeof obj[key] == 'object') {//如:key是wife,引用类型,那就递归
if (obj[key] instanceof Array) {
let newarr = []
for (var j in obj[key]) {
newarr[j] = obj[key][j]
}
newObj[key] = newarr
} else {
newObj[key] = copyObj(obj[key])
}
} else {//基本类型,直接赋值
newObj[key] = obj[key];
}
}
return newObj;
}
let pNew = copyObj(p);
pNew.books[1] = '马'
pNew.id = '111111111'
pNew.wife.address.city = '河北'
console.log(pNew);
console.log(p);
</script>
function deepCopy(obj){
//判断是否是简单数据类型,
if(typeof obj == "object"){
//复杂数据类型
var result = obj.constructor == Array ? [] : {};
for(let i in obj){
result[i] = typeof obj[i] == "object" ? deepCopy(obj[i]) : obj[i];
}
}else {
//简单数据类型 直接 == 赋值
var result = obj;
}
return result;
}