is-copy-deep.js 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. 'use strict';
  2. var eq = require('./eq')
  3. , isPlainObject = require('./is-plain-object')
  4. , value = require('./valid-value')
  5. , isArray = Array.isArray, keys = Object.keys
  6. , propertyIsEnumerable = Object.prototype.propertyIsEnumerable
  7. , eqArr, eqVal, eqObj;
  8. eqArr = function (a, b, recMap) {
  9. var i, l = a.length;
  10. if (l !== b.length) return false;
  11. for (i = 0; i < l; ++i) {
  12. if (a.hasOwnProperty(i) !== b.hasOwnProperty(i)) return false;
  13. if (!eqVal(a[i], b[i], recMap)) return false;
  14. }
  15. return true;
  16. };
  17. eqObj = function (a, b, recMap) {
  18. var k1 = keys(a), k2 = keys(b);
  19. if (k1.length !== k2.length) return false;
  20. return k1.every(function (key) {
  21. if (!propertyIsEnumerable.call(b, key)) return false;
  22. return eqVal(a[key], b[key], recMap);
  23. });
  24. };
  25. eqVal = function (a, b, recMap) {
  26. var i, eqX, c1, c2;
  27. if (eq(a, b)) return true;
  28. if (isPlainObject(a)) {
  29. if (!isPlainObject(b)) return false;
  30. eqX = eqObj;
  31. } else if (isArray(a) && isArray(b)) {
  32. eqX = eqArr;
  33. } else {
  34. return false;
  35. }
  36. c1 = recMap[0];
  37. c2 = recMap[1];
  38. i = c1.indexOf(a);
  39. if (i !== -1) {
  40. if (c2[i].indexOf(b) !== -1) return true;
  41. } else {
  42. i = c1.push(a) - 1;
  43. c2[i] = [];
  44. }
  45. c2[i].push(b);
  46. return eqX(a, b, recMap);
  47. };
  48. module.exports = function (a, b) {
  49. if (eq(value(a), value(b))) return true;
  50. return eqVal(Object(a), Object(b), [[], []]);
  51. };