is-copy-deep.js 1.5 KB

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