写一个方法,实现 javascript 中双等号==的效果,双等于底层逻辑

想看废话可以去if 与 == 与 === 与 ! 的真假判断
直接看结论就看下面的。

       //其中toNumber与toPrimitive为js的抽象操作
function toNumber(item) {
  //toNumber与Number类似
  return item.type === 'object'
    ? Number(toPrimitive(item.val))
    : Number(item.val)
}
function toPrimitive(item, type = 'number') {
  //双等于中默认想将值转化为 number 类型
  //如果 item.val 为 Date 类型则会将要转化成的类型 type 改为 string
  !(item.val instanceof Date) || (type = 'string')
  //如果想要转化成 number 则先使用 valueOf() 方法
  //如果想要转化成 string 则先使用 toSting() 方法
  if (type === 'number') {
    if (!(item.val.valueOf() instanceof Object)) {
      //如果转化成为原始值了则返回原始值
      return {
        key: item.key,
        val: item.val.valueOf(),
        type:
          item.val.valueOf() === null ? null : typeof item.val.valueOf()
      }
    } else if (typeof item.val.toString() === 'string') {
      //如果上面方法没有返回原始值,则继续用toString()
      return {
        key: item.key,
        val: item.val.toString(),
        type: 'string'
      }
    } else {
      //否则,抛出异常
      console.log('抛出异常')
    }
  } else {
    //顺序反一反
    if (typeof item.val.toString() === 'string') {
      return {
        key: item.key,
        val: item.val.toString(),
        type: 'string'
      }
    } else if (!(item.val.valueOf() instanceof Object)) {
      return {
        key: item.key,
        val: item.val.valueOf(),
        type:
          item.val.valueOf() === null ? null : typeof item.val.valueOf()
      }
    } else {
      console.log('抛出异常')
    }
  }
}
function compare(obj) {
  //为两边的值设置类型
  ; (function () {
    let { x, y } = obj
    obj = {
      x: {
        key: 'x',
        val: x,
        type: typeof x === 'function' ? 'object' : typeof x
      },
      y: {
        key: 'y',
        val: y,
        type: typeof y === 'function' ? 'object' : typeof y
      }
    }
  })()
  //判断双方类型是否相同(各种引用类型为同一种类型)
  //如果相同则返回根据三等号判断的结果
  //虽然typeof null 被识别为 'object' 也就是我们这里指的引用类型
  //但就算被识别为 object 并且另一边也为 object 时
  //经过下面判断后进行三等于运算
  //null == 任何引用类型 和 null === 任何引用类型 结果一样,都为false
  //所以不需要将它特例出来
  if (obj.x.type === obj.y.type) {
    return obj.x.val === obj.y.val
  }
  //如果x和y中有null和undefined
  //在双等于中,null与undefined判断返回true
  //并且null与undefined与其他任何类型的值都不相等
  function hasNullOrUndefined() {
    for (let key in obj) {
      if (obj[key].val === null || obj[key].val === undefined) {
        return true
      }
    }
  }
  if (hasNullOrUndefined()) {
    if (
      (obj.x.val === null && obj.y.val === undefined) ||
      (obj.y.val === null && obj.x.val === undefined)
    ) {
      return true
    } else {
      return false
    }
  }

  //过滤(隐试转换)双方值
  //如果一方有引用类型(object),用toPrimitive()转换
  ; (function () {
    for (let key in obj) {
      if (obj[key].type === 'object') {
        obj[key] = toPrimitive(obj[key])
      }
    }
  })()
    //如果一方有 boolean 类型,用Number()转换
    ; (function () {
      for (let key in obj) {
        if (obj[key].type === 'boolean') {
          obj[key].val = toNumber(obj[key])
          obj[key].type = 'number'
        }
      }
    })()
    //如果一方为Number类型,则另一方使用toNumber()
    ; (function () {
      for (let key in obj) {
        if (obj[key].type === 'number') {
          if (key === 'x') {
            obj.y.val = toNumber(obj.y)
            obj.y.type = 'number'
          } else {
            obj.x.val = toNumber(obj.x)
            obj.x.type = 'number'
          }
        }
      }
    })()
  return obj.x.val === obj.y.val
}
//比如想实现 [] == ![]
console.log(compare({ x: [], y: ![] }))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值