复杂的数据类型—传址 :赋值数据类型会出现传址情况(传递了数据和地址,共享了一块内存空间)浅拷贝:没有拷贝地址节省内存,但是因为共享内存,所有相互影响数据
let DadPro ={
name:"张三",
age:"20",
sex:"男",
}
let SonPro = DadPro;
SonPro.name ="李四";
// console.log(SonPro); console.log(DadPro.name); //李四
简单的数据类型—传值:跟深拷贝很像 复制一份A给B (不包括指针, A和B 的内存地址不一样 改变B,A的内容不发生变化)
let a = 10;
let b = a;
b = 20;
// console.log(a);
// console.log(b);
解决传址问题相互影响数据
方法一:for 循环数组 将没个参数分别赋值给数组啊arr2
缺点: 当数组中存放了引用数据时,就需要多次循环,比较复杂(遇到复杂数组比较无力)
let arr1 = [1,3,2,4,5]
let arr2 = arr1;
arr2[0] = 10;
console.log(arr1[0]) //输出10
//通过for循环后
let arr3 = [];
for (var i=0; i<arr1.length; i++){
arr3[i] = arr1[i]
}
arr3[0] = 8;
console.log(arr1[0]) //输出1 值不改变
第二种方法: forEach
```javascript
let arr4 = [1,2,3,4];
let arr5 = [];
let str = '';
arr4.forEach(function(val){
console.log(val)
str += val
})
arr5 = str.split('')
console.log(arr5)
arr5[0]= 10;
console.log(arr4[0]) //输出值为1不受影响
第三种方法: 返回一个新的对象,但是通过这个方法完成的深拷贝,会丢失函数 和undefined
JSON.stringify()把对象转换成字符串形式的JSON格式字符串值(无法转换BOM和DOM对象)
JSON.parse():把字符串形式的标准JSON字符串转换成对象(属性名必须有引号)
let arr6=[1,2,3,[2,4],{a:"abc",b:"cc"}]
// let arr7 = JSON.stringify(arr6);
// arr6 = JSON.parse(arr7);
// console.log(arr7)
// arr7[0] = 10;
// console.log(arr6[0])
// 简写
let arr7 = JSON.parse(JSON.stringify(arr6))
arr7[0] = 10;
console.log(arr6[0])
第四种方法:封装一个深拷贝方法 来直接调用
// 封装一个深拷贝方法 来直接调用
let arr7 = deepCopy(arr6);
arr7[0] = 5;
console.log(arr6);
console.log(arr7);
function deepCopy(obj){
let newObj = Array.isArray(obj)?[]:{};
//forin :会遍历对象和原型以及原型链上的方法和属性
// 但是我们做深拷贝的时候,不需要去拷贝原型链的内容
for(let key in obj){
// hasOwnProperty()用来检测指定内容是否是自身 只在自身中寻找,返回值 布尔
if(obj.hasOwnProperty()){
// 判断是否是对象(复杂数据类型)
if(typeof obj[key] === "object"){
// 如果内部的数据依然是个对象
// 再调用自身,重复检测复值一遍
newObj[key] = deepCopy(obj[key])
}else{ //简单的数据类型 直接复值
newObj[key] = obj[key]
}
}
}
// 最后 将我们检测并赋值的新对象返回!达成新内存的目的
return newObj;
}