deep_equal.js 2.8 KB

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