fork download
  1. 'use strict'
  2.  
  3. var global = this
  4. Object.isObject = Object.isObject || function isObject(obj) { return !!obj && typeof obj == 'object' }
  5.  
  6.  
  7.  
  8. function byXJSON(xjson, nativeFunc) {
  9.  
  10.  
  11. nativeFunc = nativeFunc || function $native() { throw 'This function is just a fake.' }
  12.  
  13. function parser(key, val) {
  14. try {
  15. if (typeof val == 'string' && val.match(/^function [\s\S]+?}$/))
  16. return val.match(/\(\)\s+{\s+\[native code\]\s+}$/) ? nativeFunc : eval('(' + val + ')')
  17. else return val
  18. } catch(e) {
  19. return val
  20. }
  21. }
  22.  
  23. var refs = JSON.parse(xjson, parser)
  24.  
  25.  
  26. var vals = refs.map(function (ref) {
  27. return typeof ref == 'object' ? {} : ref
  28. })
  29.  
  30. refs.reduceRight(function (goo ,ref, id) {
  31. if (!Object.isObject(ref)) return
  32. Object.keys(ref).forEach(function (key) {
  33. vals[id][key] = vals[ref[key]]
  34. })
  35. }, void 0)
  36.  
  37. //console.log(refs, vals)
  38.  
  39. return vals[0]
  40.  
  41. }
  42.  
  43.  
  44.  
  45. function toXJSON(obj, full) {
  46.  
  47. var refs = []
  48. var vals = []
  49.  
  50. conv(obj, 0)
  51.  
  52.  
  53. function conv(obj, id) {
  54.  
  55. vals[id] = obj
  56. var ref = refs[id] = {}
  57. var keys = full ? Object.getOwnPropertyNames(obj) : Object.keys(obj)
  58.  
  59. keys.forEach(function (key) {
  60. var val = obj[key]
  61.  
  62. var id = vals.indexOf(val)
  63.  
  64. if (id != -1) {
  65. ref[key] = id
  66. return
  67. }
  68.  
  69. id = vals.length
  70. ref[key] = id
  71.  
  72. if (Object.isObject(val)) {
  73. conv(val, id)
  74. } else {
  75. vals[id] = val
  76. refs[id] = val
  77. }
  78.  
  79. })
  80.  
  81. }
  82.  
  83.  
  84. //console.log(refs, vals)
  85. chkCir(refs) //循環参照をチェック
  86.  
  87. function replacer(key, val) {
  88. return typeof val == 'function' ? val.toString() : val
  89. }
  90.  
  91. return JSON.stringify(refs, replacer)
  92.  
  93. }
  94.  
  95.  
  96.  
  97. function chkCir(refs) {
  98. refs.forEach(function (ref, i) {
  99. if (!Object.isObject(ref)) return
  100. Object.keys(ref).forEach(function (key) {
  101. if (Object.isObject(ref[key])) console.log('chkerr', i, key)
  102. })
  103. })
  104. }
  105.  
  106.  
  107.  
  108. function test(id, obj, full, nativeFunc) {
  109.  
  110. var xjson = toXJSON(obj, full)
  111. var xobj = byXJSON(xjson, nativeFunc)
  112. console.group && console.group('test ' + id)
  113. console.log(xjson)
  114. console.dir(xobj)
  115. console.dir(obj)
  116. console.groupEnd && console.groupEnd('test ' + id)
  117.  
  118. }
  119.  
  120.  
  121. function testing() {
  122. var obj1 = {
  123. a: {
  124. b: {
  125. c: {},
  126. d: 'xyz',
  127. e: {}
  128. },
  129. f: 123,
  130. },
  131. g: [0,1,2,3]
  132. }
  133.  
  134. obj1.a.b.c = obj1
  135. obj1.a.b.e = obj1.a
  136.  
  137.  
  138. test(1, obj1)
  139. test(2, Math, true)
  140. test(3, global)
  141.  
  142. }
  143.  
  144.  
  145. testing()
Success #stdin #stdout 0.06s 10664KB
stdin
Standard input is empty
stdout
[{"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] }
{}
[{}]
{}
{}