'use strict' var global = this Object.isObject = Object.isObject || function isObject(obj) { return !!obj && typeof obj == 'object' } function byXJSON(xjson, nativeFunc) { nativeFunc = nativeFunc || function $native() { throw 'This function is just a fake.' } function parser(key, val) { try { if (typeof val == 'string' && val.match(/^function [\s\S]+?}$/)) return val.match(/\(\)\s+{\s+\[native code\]\s+}$/) ? nativeFunc : eval('(' + val + ')') else return val } catch(e) { return val } } var refs = JSON.parse(xjson, parser) var vals = refs.map(function (ref) { return typeof ref == 'object' ? {} : ref }) refs.reduceRight(function (goo ,ref, id) { if (!Object.isObject(ref)) return Object.keys(ref).forEach(function (key) { vals[id][key] = vals[ref[key]] }) }, void 0) //console.log(refs, vals) return vals[0] } function toXJSON(obj, full) { var refs = [] var vals = [] conv(obj, 0) function conv(obj, id) { vals[id] = obj var ref = refs[id] = {} var keys = full ? Object.getOwnPropertyNames(obj) : Object.keys(obj) keys.forEach(function (key) { var val = obj[key] var id = vals.indexOf(val) if (id != -1) { ref[key] = id return } id = vals.length ref[key] = id if (Object.isObject(val)) { conv(val, id) } else { vals[id] = val refs[id] = val } }) } //console.log(refs, vals) chkCir(refs) //循環参照をチェック function replacer(key, val) { return typeof val == 'function' ? val.toString() : val } return JSON.stringify(refs, replacer) } function chkCir(refs) { refs.forEach(function (ref, i) { if (!Object.isObject(ref)) return Object.keys(ref).forEach(function (key) { if (Object.isObject(ref[key])) console.log('chkerr', i, key) }) }) } function test(id, obj, full, nativeFunc) { var xjson = toXJSON(obj, full) var xobj = byXJSON(xjson, nativeFunc) console.group && console.group('test ' + id) console.log(xjson) console.dir(xobj) console.dir(obj) console.groupEnd && console.groupEnd('test ' + id) } function testing() { var obj1 = { a: { b: { c: {}, d: 'xyz', e: {} }, f: 123, }, g: [0,1,2,3] } obj1.a.b.c = obj1 obj1.a.b.e = obj1.a test(1, obj1) test(2, Math, true) test(3, global) } testing()
Standard input is empty
[{"a":1,"g":5},{"b":2,"f":4},{"c":0,"d":3,"e":1},"xyz",123,{"0":6,"1":7,"2":8,"3":9},0,1,2,3] { a: { b: { c: [Circular], d: 'xyz', e: [Circular] }, f: 123 }, g: { '0': 0, '1': 1, '2': 2, '3': 3 } } { a: { b: { c: [Circular], d: 'xyz', e: [Circular] }, f: 123 }, g: [ 0, 1, 2, 3 ] } [{"tan":1,"LN10":2,"E":3,"ceil":4,"atan2":5,"random":6,"LN2":7,"LOG2E":8,"sin":9,"cos":10,"pow":11,"SQRT2":12,"floor":13,"abs":14,"PI":15,"SQRT1_2":16,"acos":17,"log":18,"sqrt":19,"min":20,"exp":21,"asin":22,"round":23,"max":24,"LOG10E":25,"atan":26},"function tan() { [native code] }",2.302585092994046,2.718281828459045,"function ceil() { [native code] }","function atan2() { [native code] }","function random() { [native code] }",0.6931471805599453,1.4426950408889634,"function sin() { [native code] }","function cos() { [native code] }","function pow() { [native code] }",1.4142135623730951,"function floor() { [native code] }","function abs() { [native code] }",3.141592653589793,0.7071067811865476,"function acos() { [native code] }","function log() { [native code] }","function sqrt() { [native code] }","function min() { [native code] }","function exp() { [native code] }","function asin() { [native code] }","function round() { [native code] }","function max() { [native code] }",0.4342944819032518,"function atan() { [native code] }"] { tan: [Function: $native], LN10: 2.302585092994046, E: 2.718281828459045, ceil: [Function: $native], atan2: [Function: $native], random: [Function: $native], LN2: 0.6931471805599453, LOG2E: 1.4426950408889634, sin: [Function: $native], cos: [Function: $native], pow: [Function: $native], SQRT2: 1.4142135623730951, floor: [Function: $native], abs: [Function: $native], PI: 3.141592653589793, SQRT1_2: 0.7071067811865476, acos: [Function: $native], log: [Function: $native], sqrt: [Function: $native], min: [Function: $native], exp: [Function: $native], asin: [Function: $native], round: [Function: $native], max: [Function: $native], LOG10E: 0.4342944819032518, atan: [Function: $native] } {} [{}] {} {}