deep_equal.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. 'use strict';
  2. var traverse = require('../../');
  3. function toS(o) {
  4. return Object.prototype.toString.call(o);
  5. }
  6. module.exports = function (a, b) {
  7. if (arguments.length !== 2) {
  8. throw new Error('deepEqual requires exactly two objects to compare against');
  9. }
  10. var equal = true;
  11. function notEqual() {
  12. equal = false;
  13. // this.stop();
  14. return undefined;
  15. }
  16. var node = b;
  17. traverse(a).forEach(function (y) { // eslint-disable-line consistent-return
  18. // if (node === undefined || node === null) return notEqual();
  19. if (!this.isRoot) {
  20. /*
  21. if (!Object.hasOwnProperty.call(node, this.key)) {
  22. return notEqual();
  23. }
  24. */
  25. if (typeof node !== 'object') { return notEqual(); }
  26. node = node[this.key];
  27. }
  28. var x = node;
  29. this.post(function () {
  30. node = x;
  31. });
  32. if (this.circular) {
  33. if (traverse(b).get(this.circular.path) !== x) { notEqual(); }
  34. } else if (typeof x !== typeof y) {
  35. notEqual();
  36. } else if (x === null || y === null || x === undefined || y === undefined) {
  37. if (x !== y) { notEqual(); }
  38. } else if (x.__proto__ !== y.__proto__) {
  39. notEqual();
  40. } else if (x === y) {
  41. // nop
  42. } else if (typeof x === 'function') {
  43. if (x instanceof RegExp) {
  44. // both regexps on account of the __proto__ check
  45. if (String(x) !== String(y)) { notEqual(); }
  46. } else if (x !== y) { notEqual(); }
  47. } else if (typeof x === 'object') {
  48. if (toS(y) === '[object Arguments]'
  49. || toS(x) === '[object Arguments]') {
  50. if (toS(x) !== toS(y)) {
  51. notEqual();
  52. }
  53. } else if (toS(y) === '[object RegExp]'
  54. || toS(x) === '[object RegExp]') {
  55. if (!x || !y || x.toString() !== y.toString()) { notEqual(); }
  56. } else if (x instanceof Date || y instanceof Date) {
  57. if (!(x instanceof Date) || !(y instanceof Date)
  58. || x.getTime() !== y.getTime()) {
  59. notEqual();
  60. }
  61. } else {
  62. var kx = Object.keys(x);
  63. var ky = Object.keys(y);
  64. if (kx.length !== ky.length) { return notEqual(); }
  65. for (var i = 0; i < kx.length; i++) {
  66. var k = kx[i];
  67. if (!Object.hasOwnProperty.call(y, k)) {
  68. notEqual();
  69. }
  70. }
  71. }
  72. }
  73. });
  74. return equal;
  75. };