场景出现于;
在列表(表格)渲染的时候,渲染完毕
点击表格中的每个修改按钮
定义一个空对象,this.details = {}
拿到每个表格中的item[i] 赋值给详情 this.details = this.table[1]
这里修改详情的时候, 表格中的item[1] 也会随之变动. 这就是堆中的引用地址的问题.
现在代码解释一下:
// 1.先理解堆和栈
// 栈 : 基本类型 -> number string null undefin boolean
// 栈 : 引用类型 -> object(对象) Array(数组) date(日期) 等...
let str = 'string' //栈
console.log("str",str) //string
let str1 = str //栈
console.log("str1",str1) // string
let arr = ["a","b","c"]; //堆 列如引用地址为:abc2468
console.log("arr",arr) //["a","b","c"]
let arr1 = arr //堆 引用地址为:abc2468
console.log("arr1",arr1) //["a","b","c"]
然后在给个图, 更好的理解.
然后我们继续 , 把arr1[0] 修改成 “y” 如代码:
// 如果我修改arr1 数组中的数据 例如
let arr = ["a","b","c"]; //堆 列如引用地址为:abc2468
let arr1 = arr //堆 引用地址为:abc2468
arr1[0] = 'y'
// 把arr 和 arr1 输出出来看看
console.log("arr",arr) //["y","b","c"] 堆的地址为:abc2468
console.log("arr1",arr1) //["y","b","c"] 堆的地址为:abc2468
如图:
好了, 现在把堆和栈理解到这里了, 下面我们来认识一下 浅拷贝和深拷贝
先看看我们的测试obj的数据看看引用类型
let obj = {
name:"王五",
age:"25",
sex:"男",
details:{
type:"IT"
},
getName:function(){
console.log(this.name);
},
number1:NaN,
objNull:null,
objUndefin:undefined,
}
console.log("obj",obj)
// 输出的结果为:
// age: "25"
// details: {type: "IT"}
// getName: ƒ ()
// name: "王五"
// number1: NaN
// objNull: null
// objUndefin: undefined
// sex: "男"
// 我们先给newObj 赋值
let newObj = obj;
// 在给newObj修改年龄
newObj.age = "18";
// 然后把obj 和 newObj 打印出来看看
console.log("obj",obj)
// obj 输出的结果
// age: "18"
// details: {type: "IT"}
// getName: ƒ ()
// name: "王五"
// number1: NaN
// objNull: null
// objUndefin: undefined
// sex: "男"
console.log("newObj",newObj);
// newObj输出的结果
// age: "18"
// details: {type: "IT"}
// getName: ƒ ()
// name: "王五"
// number1: NaN
// objNull: null
// objUndefin: undefined
// sex: "男"
// 结果修改的是一个堆里面的地址 所以输出的结果一样.
- 浅拷贝:
// 浅拷贝
let obj = {
name:"王五",
age:"25",
sex:"男",
details:{
type:"IT"
},
getName:function(){
console.log(this.name);
},
number1:NaN,
objNull:null,
objUndefin:undefined,
}
let newObj2 = Object.assign({},obj);//合拼对象\
// 修改年龄
newObj2.age = "30";
// 浅拷贝的弊端在这里, 对象里面的对象修改后还是 在一个引用地址 例如我修改了details对象里面的属性
newObj2.details.type = "c++";
console.log("obj",obj)
// obj输出结果为:
// age: "25"
// details: {type: "c++"} //这里就是浅拷贝的弊端
// getName: ƒ ()
// name: "王五"
// number1: NaN
// objNull: null
// objUndefin: undefined
// sex: "男"
console.log("newObj2",newObj2)
// newObj2输出结果为:
// age: "30"
// details: {type: "c++"} //这里就是浅拷贝的弊端
// getName: ƒ ()
// name: "王五"
// number1: NaN
// objNull: null
// objUndefin: undefined
// sex: "男"
浅拷贝的第二种方法(es6): let newObj2 ={…obj}
// 浅拷贝
let obj = {
name:"王五",
age:"25",
sex:"男",
details:{
type:"IT"
},
getName:function(){
console.log(this.name);
},
number1:NaN,
objNull:null,
objUndefin:undefined,
}
let newObj2 ={...obj}
// 修改年龄
newObj2.age = "30";
// 浅拷贝的弊端在这里, 对象里面的对象修改后还是 在一个引用地址 例如我修改了details对象里面的属性
newObj2.details.type = "c++";
console.log("obj",obj)
// obj输出结果为:
// age: "25"
// details: {type: "c++"} //这里就是浅拷贝的弊端
// getName: ƒ ()
// name: "王五"
// number1: NaN
// objNull: null
// objUndefin: undefined
// sex: "男"
console.log("newObj2",newObj2)
// newObj2输出结果为:
// age: "30"
// details: {type: "c++"} //这里就是浅拷贝的弊端
// getName: ƒ ()
// name: "王五"
// number1: NaN
// objNull: null
// objUndefin: undefined
// sex: "男"
- 深拷贝 (解决浅拷贝弊端)
// 深拷贝
let obj= {
name:"王五",
age:"25",
sex:"男",
details:{
type:"IT"
},
getName:function(){
console.log(this.name);
},
number1:NaN,
objNull:null,
objUndefin:undefined,
}
let newObj = JSON.parse(JSON.stringify(obj))
// 修改年龄
newObj.age = "30";
// 修改对象里面的对象
newObj.details.type = "c++";
// 输出结果看看
console.log("obj",obj)
// 输出obj的结果为:
// age: "25"
// details: {type: "IT"}
// getName: ƒ ()
// name: "王五"
// number1: NaN
// objNull: null
// objUndefin: undefined
// sex: "男"
console.log("newObj",newObj)
// 输出newObj的结果为:
// age: "30"
// details: {type: "c++"}
// name: "王五"
// number1: null
// objNull: null
// sex: "男"
// 感觉深拷贝是解决了对象里面的对象 但是又发现了问题
// number字段变成:null;
// objUndefin字段不见了;
// getName字段方法也不见了.
// 一般使用JSON方法已经够用了
// 然后我们继续吧
完整版递归拷贝
let obj = {
name:"王五",
age:"25",
sex:"男",
details:{
type:"IT"
},
getName:function(){
console.log(this.name);
},
number1:NaN,
objNull:null,
objUndefin:undefined,
}
function deepClone(obj){
if(obj instanceof Function){
return obj
}else if(obj instanceof Array){ //如果是数组,循环数组的每一项,递归调用deepclone
return obj.map(item=>deepClone(item))
}else if(obj instanceof Object){
let newObj = {};
for(let key in obj){
newObj[key] = deepClone(obj[key])
}
return newObj
}else{
return obj;
}
}
let newObj = deepClone(obj)
// 修改年龄
newObj.age = "30";
// 修改对象里面的对象
newObj.details.type = "c++";
console.log("obj",obj)
// 输出obj的结果为:
// age: "25"
// details: {type: "IT"}
// getName: ƒ ()
// name: "王五"
// number1: NaN
// objNull: null
// objUndefin: undefined
// sex: "男"
console.log("newObj",newObj)
// 输出newObj的结果为:
// age: "30"
// details: {type: "c++"}
// getName: ƒ ()
// name: "王五"
// number1: NaN
// objNull: null
// objUndefin: undefined
// sex: "男"
// 完
如有喜欢的小伙伴,或解决你的问题,麻烦点个赞,以便后续的小伙伴需要,谢谢!! 如有写错,请提点,谢谢.
学到的就要教人,赚到的就要给人。