Last active
June 5, 2025 05:07
-
-
Save yuri-kiss/3f631f66ec0220e7359af6729b352442 to your computer and use it in GitHub Desktop.
Unfinished object comparison inspired by mist's attempt. https://github.com/Mistium/mist.js/blob/main/mist.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// latest edit: NaN checking | |
function ocom(a, b) { | |
// Fast check. | |
if (Object.is(a, b) || (a === b) || (Number.isNaN(a) && Number.isNaN(b))) return true; | |
// The === would have caught it if they were the same. | |
if (a instanceof Symbol || b instanceof Symbol) return false; | |
// Custom matcher. | |
if (a[ocom.matcher] && b[ocom.matcher]) return !!a[ocom.matcher](b); | |
// Continue the === thing. | |
if (typeof a !== 'object') return false; | |
// Prototype checking. | |
if (!Object.is( | |
Object.getPrototypeOf(a), | |
Object.getPrototypeOf(b), | |
)) return false; | |
// Checking the value. | |
if (Object.is(Object.getPrototypeOf(a), Object)) { | |
// fallthrough, this is just faster | |
} else if (Array.isArray(a)) { | |
if (a.length !== b.length) return false; | |
// Check all the values. | |
for (let i = a.length - 1; i > -1; --i) { | |
if (!ocom(a[i], b[i])) return false; | |
} | |
return true; | |
} else if (a instanceof Map) { | |
// Pass the load to the array handler. | |
return ocom( | |
a.entries().toArray(), | |
b.entries().toArray(), | |
); | |
} else if (a instanceof Set || a instanceof ocom.TypedArray) { | |
return ocom(Array.from(a), Array.from(b)); | |
} else if (a instanceof DataView || a instanceof ArrayBuffer) { | |
if (a instanceof DataView) { | |
a = a.buffer; | |
b = b.buffer; | |
} | |
return ocom(Array.from(new Uint8Array(a)), Array.from(new Uint8Array(b))); | |
} | |
const keysA = Object.getOwnPropertyNames(a).concat(Object.getOwnPropertySymbols(a)); | |
const keysB = Object.getOwnPropertyNames(b).concat(Object.getOwnPropertySymbols(b)); | |
if (keysA.length !== keysB.length) return false; | |
for (let i = keysA.length - 1; i > -1; --i) { | |
if (!ocom(keysA[i], keysB[i])) return false; | |
} | |
const valsA = Object.values(a); | |
const valsB = Object.values(b); | |
if (valsA.length !== valsB.length) return false; | |
for (let i = valsA.length - 1; i > -1; --i) { | |
if (!ocom(valsA[i], valsB[i])) return false; | |
} | |
return true; | |
} | |
ocom.TypedArray = Object.getPrototypeOf(Uint8Array); | |
ocom.matcher = Symbol('ObjectCompare.customMatch'); | |
console.log(ocom({ x: 1 }, { x: 1 })); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment