# All files / utils isEqual.ts

82.35% Statements 56/68
59.25% Branches 32/54
80% Functions 4/5
83.58% Lines 56/67

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    1174x

    4x

    4x

    4x

    4x
    10x

    4x
    130x
    1x

    129x
    78x

    51x
    1x

    50x
    4x

    46x
    46x
    8x

    38x

    4x
    38x
    38x

    38x

    38x
    38x
    7x
    1x

    6x
    6x
    6x

    37x
    37x
    37x
    37x
    31x

    37x
    37x
    37x
    31x
    31x
    1x

    30x
    75x
    1x

    6x
    6x
    6x
    6x

    6x
    10x
    10x

    35x
    35x
    35x

    4x
    45x

     import {getJavaScriptTag} from './getJavaScriptTag'

    const SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null

    const isFunction = value => typeof value === 'function'

    const hasOwnProperty = Object.prototype.hasOwnProperty

    const _has = (obj, path) => {
      return obj != null && hasOwnProperty.call(obj, path)
    }

    const eq = (a, b, aStack?, bStack?) => {
      if (Number.isNaN(a) && Number.isNaN(b)) {
        return false
      }

      if (a === b) {
        return a !== 0 || 1 / a === 1 / b
      }
      if (a == null || b == null) {
        return false
      }
      if (a !== a) {
        return b !== b
      }
      const type = typeof a
      if (type !== 'function' && type !== 'object' && typeof b != 'object') {
        return false
      }
      return deepEq(a, b, aStack, bStack)
    }

    const deepEq = (a, b, aStack?, bStack?) => {
      const className = getJavaScriptTag(a)
      Iif (className !== getJavaScriptTag(b)) {
        return false
      }
      switch (className) {
        case '[object RegExp]':
        case '[object String]':
          return '' + a === '' + b
        case '[object Number]':
          Iif (+a !== +a) {
            return +b !== +b
          }
          return +a === 0 ? 1 / +a === 1 / b : +a === +b
        case '[object Date]':
        case '[object Boolean]':
          return +a === +b
        case '[object Symbol]':
          return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b)
      }
      const areArrays = className === '[object Array]'
      if (!areArrays) {
        if (typeof a != 'object' || typeof b != 'object') {
          return false
        }
        const aCtor = a.constructor,
          bCtor = b.constructor
        Iif (
          aCtor !== bCtor &&
          !(
            isFunction(aCtor) &&
            aCtor instanceof aCtor &&
            isFunction(bCtor) &&
            bCtor instanceof bCtor
          ) &&
          'constructor' in a &&
          'constructor' in b
        ) {
          return false
        }
      }
      aStack = aStack || []
      bStack = bStack || []
      let length = aStack.length
      while (length--) {
        Iif (aStack[length] === a) {
          return bStack[length] === b
        }
      }
      aStack.push(a)
      bStack.push(b)
      if (areArrays) {
        length = a.length
        if (length !== b.length) {
          return false
        }
        while (length--) {
          if (!eq(a[length], b[length], aStack, bStack)) {
            return false
          }
        }
      } else {
        const _keys = Object.keys(a)
        let key
        length = _keys.length
        Iif (Object.keys(b).length !== length) {
          return false
        }
        while (length--) {
          key = _keys[length]
          Iif (!(_has(b, key) && eq(a[key], b[key], aStack, bStack))) {
            return false
          }
        }
      }
      aStack.pop()
      bStack.pop()
      return true
    }

    export const isEqual = (a?, b?): boolean => {
      return eq(a, b)
    }