Skip to content

Instantly share code, notes, and snippets.

@c7x43t
Last active December 14, 2021 12:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save c7x43t/a378b26279ffb8cd1b5038e713fd8974 to your computer and use it in GitHub Desktop.
Save c7x43t/a378b26279ffb8cd1b5038e713fd8974 to your computer and use it in GitHub Desktop.
// 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