堆存放引用数据类型 栈存放简单数据类型 引用数据类型在栈上储存的是指向堆的地址
对象,数组是引用数据类型,会在堆里面开辟一个空间存,然后在栈里存一个地址,指向堆
浅拷贝的时候实际上是拷贝的栈的地址,
浅拷贝:(for in 循环赋值 / Object.assign(新对象,旧对象))
可以复制当前一层的内容,深一层的内容无法复制,修改了新的数据之后,原本的数据也会被修改
// 浅拷贝的实现 通过for in实现
var user1 = {
name: "小明",
age: 30,
height: 1.9
};
var user2 = {};
for (var i in user1) {
user2[i] = user1[i]; //user[i]输出的是每一个值,将user1的每一个值赋予给user2对象
}
console.log(user2) //{name: "小明", age: 30, height: 1.9}
// 浅拷贝 通过Object.assign({}, 对象1, 对象2);
// 这一种浅拷贝方式类似于jquery的$.extend({}, 对象1, 对象2)
var obj1 = {
name: "小明",
age: 13
};
var obj2 = {
name: "大王",
tel: 18456888
};
var obj = Object.assign({}, obj1, obj2);
console.log(obj) //{name: "大王", age: 13, tel: 18456888}
// 我们发现这一种方式,相同的key值后一个会覆盖前一个的key值,
深拷贝就是拷贝堆的内容,
在复制之后需要对每个成员项 再进行一次数据类型判断 , 以后每一层的数据都会被拷贝实现深拷贝的方法:
1.通过JSON.转换成字符再转回来
2.遍历递归
3.lodash插件
//原数据,包含字符串、对象、函数、数组等不同的类型
var obj = {
name:"test",
main:{
a:1,
b:2
},
fn:function(){
},
friends:[1,2,3,[22,33]]
}
//遍历递归
function deepcopy(obj) {
if (obj instanceof Object) {
const newObj = new obj.constructor();
for (let key in obj) {
newObj[key] = deepcopy(obj[key]);
}
return newObj
}
return obj;
}
const o = deepcopy(obj);
console.log(o.name = "修改成功");
console.log(o);
console.log(obj);
刘金萍案例
var a = [
{
name: "jinping",
gender: "female",
age: "18",
},
{
name: "qiumo",
gender: "male",
age: "19",
},
];
//深拷贝1
var b = [];
for (let i = 0; i < a.length; i++) {
b[i] = {...a[i]} ;
}
//深拷贝2
var b = JSON.parse(JSON.stringify(a)) //我们一般用来深拷贝
// 浅拷贝
var c=a;
b[0].name = "huimin";
console.log(a);//深拷贝不变,浅拷贝变
console.log(b);