Last active
December 14, 2021 12:14
-
-
Save c7x43t/a378b26279ffb8cd1b5038e713fd8974 to your computer and use it in GitHub Desktop.
This file contains 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
// Primitives, Date, RegExp, Functions, all Arrays, Object, Object with null Prototype, all Errors, circular Objects, Map, Set, Fuction Arguments | |
// ToDo: self referencing structures are not correcly handled (in certain cases non-self referencing structures are falsely labeled), but they never fail to stringify | |
// Notes: https://stackoverflow.com/questions/8511281/check-if-a-value-is-an-object-in-javascript/53263848#53263848 | |
var objectHash = (function(){ | |
var primitiveTypes = new Set(); | |
primitiveTypes.add('Date'); | |
primitiveTypes.add('RegExp'); | |
primitiveTypes.add('Number'); | |
primitiveTypes.add('String'); | |
primitiveTypes.add('Boolean'); | |
primitiveTypes.add('Function'); | |
var arrayTypes = new Set(); | |
arrayTypes.add('Array'); | |
arrayTypes.add('Int8Array'); | |
arrayTypes.add('Uint8Array'); | |
arrayTypes.add('Uint8ClampedArray'); | |
arrayTypes.add('Int16Array'); | |
arrayTypes.add('Uint16Array'); | |
arrayTypes.add('Int32Array'); | |
arrayTypes.add('Uint32Array'); | |
arrayTypes.add('Float32Array'); | |
arrayTypes.add('Float64Array'); | |
arrayTypes.add('BigInt64Array'); | |
arrayTypes.add('BigUint64Array'); | |
var errorTypes = new Set(); | |
errorTypes.add('Error'); | |
errorTypes.add('AggregateError'); | |
errorTypes.add('EvalError'); | |
errorTypes.add('InternalError'); | |
errorTypes.add('RangeError'); | |
errorTypes.add('ReferenceError'); | |
errorTypes.add('SyntaxError'); | |
errorTypes.add('TypeError'); | |
errorTypes.add('URIError'); | |
function isPrimitive(o){return typeof o!=='object'||o===null} | |
function objectHash(o,keySet,ctx,level=0){ | |
if(isPrimitive(o)||errorTypes.has(o)) return String(o); | |
// if(o instanceof Function) return o.toString(); | |
if(!(ctx instanceof Map)){ | |
ctx = new Map(); | |
ctx.__counter__ = 0; | |
} | |
if(!ctx.has(o)){ | |
ctx.set(o,[ctx.__counter__++,level]) | |
}else{ | |
let c = ctx.get(o); | |
if(c[1]<level){ | |
return 'Self Reference#{'+c[0]+'}'; | |
} | |
} | |
if(o instanceof Object){ | |
if(o.hasOwnProperty('callee')&&o.callee instanceof Function && o.hasOwnProperty('length')){ | |
let s = 'Arguments['; | |
for(var i=0;i<o.length;i++) s+=objectHash(o[i],undefined,ctx,++level)+','; | |
return s+']'; | |
} | |
let constructorName = Object.getPrototypeOf(o).constructor.name; | |
if(arrayTypes.has(constructorName)) return constructorName+'['+o.map(function(o){return objectHash(o,undefined,ctx,++level)}).join(',')+']'; | |
// assume Object | |
let s = constructorName +'{'; | |
if(primitiveTypes.has(Object.getPrototypeOf(o).constructor.name)) return s + String(o)+'}'; | |
if(o instanceof Map){ | |
o.forEach(function(key,value){s+=objectHash(key,undefined,ctx,++level)+'=>'+objectHash(value,undefined,ctx,++level)+','}); | |
}else if(o instanceof Set){ | |
o.forEach(function(value){s+=objectHash(value,undefined,ctx,++level)+','}) | |
}else{ | |
let keys = keySet instanceof Array ? keySet : Object.keys(o); | |
for(let key of keys) if(Object.prototype.hasOwnProperty.call(o,key)) s+=key+':'+objectHash(o[key],undefined,ctx,++level)+','; | |
} | |
return s+'}'; | |
}else{ | |
let s= 'null{'; | |
let keys = keySet instanceof Array ? keySet : Object.keys(o); | |
for(let key of keys) if(Object.prototype.hasOwnProperty.call(o,key)) s+=key+':'+objectHash(o[key],undefined,ctx,++level)+','; | |
return s+'}'; | |
} | |
} | |
return objectHash; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment