You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							112 lines
						
					
					
						
							3.4 KiB
						
					
					
				
			
		
		
	
	
							112 lines
						
					
					
						
							3.4 KiB
						
					
					
				var objectKeys = require('object-keys'); | 
						|
var isArguments = require('is-arguments'); | 
						|
var is = require('object-is'); | 
						|
var isRegex = require('is-regex'); | 
						|
var flags = require('regexp.prototype.flags'); | 
						|
var isDate = require('is-date-object'); | 
						|
 | 
						|
var getTime = Date.prototype.getTime; | 
						|
 | 
						|
function deepEqual(actual, expected, options) { | 
						|
  var opts = options || {}; | 
						|
 | 
						|
  // 7.1. All identical values are equivalent, as determined by ===. | 
						|
  if (opts.strict ? is(actual, expected) : actual === expected) { | 
						|
    return true; | 
						|
  } | 
						|
 | 
						|
  // 7.3. Other pairs that do not both pass typeof value == 'object', equivalence is determined by ==. | 
						|
  if (!actual || !expected || (typeof actual !== 'object' && typeof expected !== 'object')) { | 
						|
    return opts.strict ? is(actual, expected) : actual == expected; | 
						|
  } | 
						|
 | 
						|
  /* | 
						|
   * 7.4. For all other Object pairs, including Array objects, equivalence is | 
						|
   * determined by having the same number of owned properties (as verified | 
						|
   * with Object.prototype.hasOwnProperty.call), the same set of keys | 
						|
   * (although not necessarily the same order), equivalent values for every | 
						|
   * corresponding key, and an identical 'prototype' property. Note: this | 
						|
   * accounts for both named and indexed properties on Arrays. | 
						|
   */ | 
						|
  // eslint-disable-next-line no-use-before-define | 
						|
  return objEquiv(actual, expected, opts); | 
						|
} | 
						|
 | 
						|
function isUndefinedOrNull(value) { | 
						|
  return value === null || value === undefined; | 
						|
} | 
						|
 | 
						|
function isBuffer(x) { | 
						|
  if (!x || typeof x !== 'object' || typeof x.length !== 'number') { | 
						|
    return false; | 
						|
  } | 
						|
  if (typeof x.copy !== 'function' || typeof x.slice !== 'function') { | 
						|
    return false; | 
						|
  } | 
						|
  if (x.length > 0 && typeof x[0] !== 'number') { | 
						|
    return false; | 
						|
  } | 
						|
  return true; | 
						|
} | 
						|
 | 
						|
function objEquiv(a, b, opts) { | 
						|
  /* eslint max-statements: [2, 50] */ | 
						|
  var i, key; | 
						|
  if (typeof a !== typeof b) { return false; } | 
						|
  if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) { return false; } | 
						|
 | 
						|
  // an identical 'prototype' property. | 
						|
  if (a.prototype !== b.prototype) { return false; } | 
						|
 | 
						|
  if (isArguments(a) !== isArguments(b)) { return false; } | 
						|
 | 
						|
  var aIsRegex = isRegex(a); | 
						|
  var bIsRegex = isRegex(b); | 
						|
  if (aIsRegex !== bIsRegex) { return false; } | 
						|
  if (aIsRegex || bIsRegex) { | 
						|
    return a.source === b.source && flags(a) === flags(b); | 
						|
  } | 
						|
 | 
						|
  if (isDate(a) && isDate(b)) { | 
						|
    return getTime.call(a) === getTime.call(b); | 
						|
  } | 
						|
 | 
						|
  var aIsBuffer = isBuffer(a); | 
						|
  var bIsBuffer = isBuffer(b); | 
						|
  if (aIsBuffer !== bIsBuffer) { return false; } | 
						|
  if (aIsBuffer || bIsBuffer) { // && would work too, because both are true or both false here | 
						|
    if (a.length !== b.length) { return false; } | 
						|
    for (i = 0; i < a.length; i++) { | 
						|
      if (a[i] !== b[i]) { return false; } | 
						|
    } | 
						|
    return true; | 
						|
  } | 
						|
 | 
						|
  if (typeof a !== typeof b) { return false; } | 
						|
 | 
						|
  try { | 
						|
    var ka = objectKeys(a); | 
						|
    var kb = objectKeys(b); | 
						|
  } catch (e) { // happens when one is a string literal and the other isn't | 
						|
    return false; | 
						|
  } | 
						|
  // having the same number of owned properties (keys incorporates hasOwnProperty) | 
						|
  if (ka.length !== kb.length) { return false; } | 
						|
 | 
						|
  // the same set of keys (although not necessarily the same order), | 
						|
  ka.sort(); | 
						|
  kb.sort(); | 
						|
  // ~~~cheap key test | 
						|
  for (i = ka.length - 1; i >= 0; i--) { | 
						|
    if (ka[i] != kb[i]) { return false; } | 
						|
  } | 
						|
  // equivalent values for every corresponding key, and ~~~possibly expensive deep test | 
						|
  for (i = ka.length - 1; i >= 0; i--) { | 
						|
    key = ka[i]; | 
						|
    if (!deepEqual(a[key], b[key], opts)) { return false; } | 
						|
  } | 
						|
 | 
						|
  return true; | 
						|
} | 
						|
 | 
						|
module.exports = deepEqual;
 | 
						|
 |