浅拷贝、深拷贝和浅比较、深比较的理解

一、浅拷贝和深拷贝

1、浅拷贝

当你去复制或者传递一个值的时候,浅拷贝会创建一个新的空间或对象,然后简单地将值复制给新的对象。

因此,对于JS中基本数据类型和引用数据类型而言,产生的效果天差地别:

  • 基本数据类型:比如number等,其创建了一个新的空间,其中复制过去的即是内容值,这样新的变量和旧的变量依旧是独立存在
  • 引用数据类型:比如object等,当创建了一个新的空间后,复制过去的是其引用的内容值,该引用的内容值指向的是其在堆空间中的实际地址。因此,在浅拷贝之后,两个对象共享同一个引用,每一次修改都是对同一个对象进行操作,因此互相影响

2、深拷贝

深拷贝也是创建了一个新的空间或对象,但是并不是简单的赋值,而是递归地将内存中所有真实保存的数据以及子数据都复制到新的空间上

对于引用数据类型而言,新空间中保存的不再是同一个引用,而是会再去堆中整个地复制对象的内部数据到新空间。

实现深拷贝的算法如下:

//递归思想
function deepClone(obj){

    if(obj === null ||typeof obj!=='object'){
        //基本数据类型直接返回
        return obj;
    }
    else{
        //创建新的堆空间和相应的引用
        let res=Array.isArray(obj)?[]:{};
        for(let k in obj){
            if(obj.hasOwnProperty(k)){
                if(obj[k] === null ||typeof obj[k]!=='object'){
                    res[k]=obj[k];
                }
                else res[k]=deepClone(obj[k]);
            }
        }
        return res;
    }

}

二、浅比较和深比较

1、浅比较 :浅比较是比较两个对象的引用是否相等,即它们是否指向同一内存地址

对于react中,useEffect往往进行的是浅比较。当传入的依赖项是一个数组或者对象时,如果每次更新数组和对象不是返回新的引用,而仅仅是直接修改其内容中的key:value则不会触发useEffect执行。

所以,对于对象,定义state,修改返回一个新的引用:

import {useState} from 'React';

export default function App(){

    const [store,setStore]=useState({value:1});
    const handleClick = ()=>{
        setStore((pre)=>{
            //返回新的引用以修改其值
            return {...pre,value:2};
        })
    }
    

    useEffect(()=>{
        console.log('new value',store.value);
    },[store])

    return(
        <button onClick={handleClick}>点击</button>
    )

}

2、深比较:深比较递归地比较对象及其子对象的内容,要求所有层次都相等才认为对象相等。

在js中===、react中useEffect、useMemo(根据依赖项缓存函数返回值,有时候也可以视作对于依赖项的一些再加工计算)的执行都根据的是浅比较,那么在写代码时候如何让其实现深比较呢?

主要方法:

1、在使用react写组件时,类组件在shouldComponentUpdate、函数组件在React.memo中自定义实现深层比较(默认都是浅比较)

2、使用JSON.stringify将数据转换为字符串类型,作为依赖项。

3、使用lodash.isEqual(第三方工具库)实现深比较

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

音仔小瓜皮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值