文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

React 中的浅比较是如何工作的?

2024-12-02 02:58

关注

要想理解浅比较的概念,最直接的方法就是研究 React 相关的源码,下面就来看看React中的shallowEqual.js 文件:

import is from './objectIs';
import hasOwnProperty from './hasOwnProperty';


function shallowEqual(objA: mixed, objB: mixed): boolean {
if (is(objA, objB)) {
return true;
}

if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}

const keysA = Object.keys(objA);
const keysB = Object.keys(objB);

if (keysA.length !== keysB.length) {
return false;
}

// Test for A's keys different from B.
for (let i = 0; i < keysA.length; i++) {
const currentKey = keysA[i];
if (
!hasOwnProperty.call(objB, currentKey) ||
!is(objA[currentKey], objB[currentKey])
) {
return false;
}
}

return true;
}

这里执行了多步操作,下面就来将其拆分并逐步解释这些功能。先来看看函数的定义,这个函数接受两个需要比较的对象,这里的代码使用 Flow 作为类型检查系统。两个函数参数都是使用特殊的混合 Flow 类型定义,类似于 TypeScript 的 unknown,它表明函数可以是任何类型的值。

function shallowEqual(objA: mixed, objB: mixed): boolean {
// ...
}

之后使用 React 内部对象的 is 函数将两个函数参数进行比较。导入的 is 函数只不过是JavaScript 的 Object.is 函数的polyfill 版本。这个比较函数基本上等同于常见的 === 运算符,但有两个例外:

基本上,第一个条件语句可以处理所有简单的情况:如果两个函数参数具有相同的值,对于原始类型,或引用相同的对象(数组和对象),那么通过浅比较认为它们相等的。

import is from './objectIs';

function shallowEqual(objA: mixed, objB: mixed): boolean {
if (is(objA, objB)) {
return true;
}
// ...
}

在处理两个函数参数值相等或者引用同一个对象的所有简单情况之后,来看看更复杂的结构:数组和对象。

为了确保现在要处理的是两个复杂的结构,代码会检查任一参数是不是object类型或者等于null,前者用来确保我们处理的数组或对象,后者用来过滤掉空值,因为typeof null的结果也是 object。如果任何一个条件成立,那两个参数一定是不相等的(否则前面的条件语句就会将它们过滤掉),因此浅比较直接返回false。

function shallowEqual(objA: mixed, objB: mixed): boolean {
// ...

if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}

// ...
}

现在就可以确保我们处理的是数组和对象了,接下来我们深入研究复杂数据结构的值,并在两个函数参数之间进行比较。在此之前,先来检查两个参数中值的数量是否相等,如果不相等,直接就可以确定两个值是不相等的。对于对象,得到的keys数组就是由实际的key组成的;对于数组,得到keys数组数是由字符串类型的数组索引组成的。

function shallowEqual(objA: mixed, objB: mixed): boolean {
// ...

const keysA = Object.keys(objA);
const keysB = Object.keys(objB);

if (keysA.length !== keysB.length) {
return false;
}

// ...
}

最后一步,按照 key 来迭代两个函数参数的值,并逐个验证他们是否是相等的。为此,代码使用到了上一步中生成的keys数组,使用 hasOwnProperty 检查key是否实际上是参数的属性,并使用 Object.is 函数进行比较。

import hasOwnProperty from './hasOwnProperty';

function shallowEqual(objA: mixed, objB: mixed): boolean {
// ...

// Test for A's keys different from B.
for (let i = 0; i < keysA.length; i++) {
const currentKey = keysA[i];
if (
!hasOwnProperty.call(objB, currentKey) ||
!is(objA[currentKey], objB[currentKey])
) {
return false;
}
}

return true;
}

如果任何两个key对应的值是不相等的,那两个对象肯定就是不相等的,因此直接人会false,结束循环。如果所有的值都是相等的,就返回 true。

至此,我们通过 React 源码学习了 React 中的浅比较,下面来总结一下:

源码:https://github.com/facebook/react/blob/main/packages/shared/shallowEqual.js

来源:前端充电宝内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯