/** * 把对象转换为 JSON 支持循环引用 */ export function json(data: any, space = 2): string { return stringify(data, null, space) } /** * 把 JSON 转换为对象 支持循环引用 */ export function fromJson(data: any): any { return parse(data) } // https://github.com/yyx990803/circular-json-es6 function encode(data: any, replacer: any, list: any, seen: any) { var stored: any, key, value, i, l var seenIndex = seen.get(data) if (seenIndex != null) { return seenIndex } var index = list.length var proto = Object.prototype.toString.call(data) if (proto === "[object Object]") { stored = {} seen.set(data, index) list.push(stored) var keys = Object.keys(data) for (i = 0, l = keys.length; i < l; i++) { key = keys[i] value = data[key] if (replacer) value = replacer.call(data, key, value) stored[key] = encode(value, replacer, list, seen) } } else if (proto === "[object Array]") { stored = [] seen.set(data, index) list.push(stored) for (i = 0, l = data.length; i < l; i++) { value = data[i] if (replacer) value = replacer.call(data, i, value) stored[i] = encode(value, replacer, list, seen) } } else { list.push(data) } return index } function decode(list: any, reviver: any) { var i = list.length var j, k, data, key, value, proto while (i--) { data = list[i] proto = Object.prototype.toString.call(data) if (proto === "[object Object]") { var keys = Object.keys(data) for (j = 0, k = keys.length; j < k; j++) { key = keys[j] value = list[data[key]] if (reviver) value = reviver.call(data, key, value) data[key] = value } } else if (proto === "[object Array]") { for (j = 0, k = data.length; j < k; j++) { value = list[data[j]] if (reviver) value = reviver.call(data, j, value) data[j] = value } } } } function stringify(data: any, replacer: any, space: any) { try { return arguments.length === 1 ? JSON.stringify(data) : JSON.stringify(data, replacer, space) } catch (e) { return stringifyStrict(data, replacer, space) } } function parse(data: any, reviver?: any) { var hasCircular = /^\s/.test(data) if (!hasCircular) { return arguments.length === 1 ? JSON.parse(data) : JSON.parse(data, reviver) } else { var list = JSON.parse(data) decode(list, reviver) return list[0] } } function stringifyStrict(data: any, replacer: any, space: any) { var list: any = [] encode(data, replacer, list, new Map()) return space ? " " + JSON.stringify(list, null, space) : " " + JSON.stringify(list) }