前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >‘underscore系列之比较两个元素是否“相同“‘

‘underscore系列之比较两个元素是否“相同“‘

作者头像
用户9298250
发布2022-01-10 13:42:09
4980
发布2022-01-10 13:42:09
举报

比较两个元素是否相同

前言

之前就说过要读一下关于underscore.js的源码, 我就想先从某个函数开始读, 正好在github文章中(这里的文章我会在最后放上地址)提到了underscore中关于如何比较两个元素的是否相同, 我看完之后觉得很好玩。那么对于如何判断两个元素是否是相同呢?那么在什么程度上才算是相同, 举个例子: 1与1是相等的(当然他们前提是类型是一样的)那么1new Number(1)也应该相等。 underscore中有这么一个函数_.isEqual对没错, 就是这个。接下来我会以自己的知识来解释下, 这个函数的涉及的知识点。 如果有解释的不好的点, 请大家给我留言我一定改正。话不多说直接开始

分析_.isEqual

Number类型判断

console.log( _.isEqual(a, b));

我首先在 _.isEqual中传入了两个参数a, b。首先明确两个概念: 其一是a, b都是基本类型, 那么两个基本类型的值相同。其二是两个是引用类型, 那么引用类型相同。如果a === b为true, 我们是否可以说a和b是相等的。但是这里有个特殊的就是0, -0。0与-0被浏览器认为是相等的。正确来讲0与-0是不相等的(关于这里我是看了文章里面有提到, 我在控制台打印了下, 发现很神奇)。关于这里_.isEqual这样处理的。

代码语言:javascript
复制
if (a === b) return a !== 0 || 1 / a === 1 / b;

我理解是这样的: 这里过滤了99%情况, 但是没有过滤掉0与-0的情况。但是return里面如果a是0, 直接就return false结束。还有就是a如果为-0呢?第一个条件满足, 我们看第二个 1 / a(-0) === -Infinity1 / b(0) === Infinity;所以第二个条件也不满足, 那么直接返回return false. ——游戏结束。上面这种判断处理就是针对0与-0这种情况。 接下来就是 a !== b 如果a或者b其中有一个为null或者是undefined特殊处理。

代码语言:javascript
复制
if (a === null || b === null) return a === b;

文章中说这里的这里的判断条件有点多余, 因为根据上面的判断条件 a === b肯定返回false。关于这里我想了想也对, 如果a === b 直接在上面的判断条件哪里直接就返回了。 所以把return a === b 替换成 retun false, 会更加清晰吧。 接下来用到了Object.prototype.toString.call, 如果判断的参数的类型不一样, 那么直接就返回return false。

代码语言:javascript
复制
var className = toString.call(a)
if (className !== toString.call(b)) return false;

如果a或者b都是Number类型, 但是这里又有一个特例就是not a number也就是NaN。这里我举个栗子: var number = new Number('s') var number2 = new Number('s'); console.log(_.isEqual(number, number2)); 这里的numbernumber2的值都是Number{NaN},而且又都是[object Number]。 理应来讲numbernumber2应该是相等的, 因为都是NaN嘛。所以这里专门针对NaN的情况做了判断, 看case里的第一个判断条件: 如果+a不等于+a那么a就是NaN, 因为NaN === NaN为false。同理b也一样如果b为NaN那么返回为true。证明a, b相等(都为NaN)。如果+b === +b 返回false, 说明a, b不相等。 下面的return这里又有一个特殊处理, 是关于0的。举个例子: var s = new Number(-0); var a = new Number(0); console.log(_.isEqual(s, a)); 首先上面已经说过了0 === -0为true, 所以第一个条件为false。正确。同理把-0换成1, 走第二个条件也是一样, 返回false, 很明显不相等。

代码语言:javascript
复制
case '[object Number]':
    // console.log('1')
      // `NaN`s are equivalent, but non-reflexive.
      // Object(NaN) is equivalent to NaN
      if (+a !== +a) return +b !== +b;
      // console.log(+b !== +b);
      // An `egal` comparison is performed for other numeric values.
      return +a === 0 ? 1 / +a === 1 / b : +a === +b;

关于对于Number类型的判断就到这里结束了。


正则RegExp和String类型判断

举个例子: var a = /a/; var b = new RegExp('a') consolo.log(_.isEqual(s, a)); 我们看下是如何处理这种情况的, 首先还是老样子判断属于什么类型, 发现是RegExp进入return 转换为字符串进行比较-也就是a与a进行比较为true。 String也一样, var a = new String('s'); var b = new String('s'); 同上。

代码语言:javascript
复制
case '[object RegExp]':
  // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
case '[object String]':
  // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
  // equivalent to `new String("5")`.
  return '' + a === '' + b;

Date与Boolean类型判断

举个栗子: 还是根据数据类型选择进入: var a = new Date(1); var b = 1 这样进行判断就会发现通过使用+new Date()或者+new Date转换成1。这样就会发现返回true; 当然我觉得布尔类型也是如此, var a = true; var b = new Boolean(false); a为true, 我们也知道true == 1, true为布尔类型进入进行隐士类型转换, b也是如此, 如果相等返回true, 否则反之。

代码语言:javascript
复制
case '[object Date]':
case '[object Boolean]':
  // Coerce dates and booleans to numeric primitive values. Dates are compared by their
  // millisecond representations. Note that invalid dates with millisecond representations
  // of `NaN` are not equivalent.
  return +a === +b;

数组与对象类型比较

关于数组的类型比较稍微比较麻烦, 因为涉及到数组有包括对象的情况。同理, 也有可能对象里面有数组的情况。还是老样子判断是否是['object Array'];


未完待续

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-12-24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 比较两个元素是否相同
    • 前言
    • 分析_.isEqual
      • Number类型判断
        • 正则RegExp和String类型判断
          • Date与Boolean类型判断
            • 数组与对象类型比较
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档