堆和栈的理解 堆和栈的区别 什么是堆和栈 堆是什么 栈是什么

场景出现于;
在列表(表格)渲染的时候,渲染完毕
点击表格中的每个修改按钮
定义一个空对象,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: "男"

// 结果修改的是一个堆里面的地址 所以输出的结果一样.
  1. 浅拷贝:
// 浅拷贝
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: "男"
  1. 深拷贝 (解决浅拷贝弊端)
// 深拷贝
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: "男"

// 完

如有喜欢的小伙伴,或解决你的问题,麻烦点个赞,以便后续的小伙伴需要,谢谢!! 如有写错,请提点,谢谢.

学到的就要教人,赚到的就要给人。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值