isEqual.js 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import warning from './warning';
  2. /**
  3. * Deeply compares two object literals.
  4. * @param obj1 object 1
  5. * @param obj2 object 2
  6. * @param shallow shallow compare
  7. * @returns
  8. */
  9. function isEqual(obj1, obj2) {
  10. let shallow = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  11. // https://github.com/mapbox/mapbox-gl-js/pull/5979/files#diff-fde7145050c47cc3a306856efd5f9c3016e86e859de9afbd02c879be5067e58f
  12. const refSet = new Set();
  13. function deepEqual(a, b) {
  14. let level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
  15. const circular = refSet.has(a);
  16. warning(!circular, 'Warning: There may be circular references');
  17. if (circular) {
  18. return false;
  19. }
  20. if (a === b) {
  21. return true;
  22. }
  23. if (shallow && level > 1) {
  24. return false;
  25. }
  26. refSet.add(a);
  27. const newLevel = level + 1;
  28. if (Array.isArray(a)) {
  29. if (!Array.isArray(b) || a.length !== b.length) {
  30. return false;
  31. }
  32. for (let i = 0; i < a.length; i++) {
  33. if (!deepEqual(a[i], b[i], newLevel)) {
  34. return false;
  35. }
  36. }
  37. return true;
  38. }
  39. if (a && b && typeof a === 'object' && typeof b === 'object') {
  40. const keys = Object.keys(a);
  41. if (keys.length !== Object.keys(b).length) {
  42. return false;
  43. }
  44. return keys.every(key => deepEqual(a[key], b[key], newLevel));
  45. }
  46. // other
  47. return false;
  48. }
  49. return deepEqual(obj1, obj2);
  50. }
  51. export default isEqual;