等价JSON输入下TOML.stringify()输出差异原因及j-toml格式控制方法
j-toml格式保留机制与自定义格式方法
一、j-toml如何「记住」原始TOML格式
j-toml在解析TOML时,会给生成的JSON对象添加不可枚举的元属性(通过Object.defineProperty这类方式添加的隐藏属性),这些属性存储着原始TOML的格式细节:比如数组的换行风格、表的定义形式、空格缩进规则等。
由于这些元属性不可枚举,JSON.stringify()序列化时不会将其包含进去,当你再用JSON.parse()解析回来,格式元数据就彻底丢失,自然无法还原原始格式。
二、如何为新增的对象字面量指定特定格式
要给手动添加的对象指定格式,有两种实用方法:
方法1:通过stringify配置统一指定风格
调用TOML.stringify()时,传入配置参数可以全局控制输出格式,比如强制数组单行显示、设置缩进宽度等:
TOML.stringify(jsonParseToml, { newline: '\n', indent: 4, // 缩进空格数 arrayNewline: false, // false表示数组元素单行显示 trailingComma: false // 是否添加尾逗号 })
方法2:解析目标格式的TOML片段生成对象
如果需要给某个特定对象指定精准格式,可以先解析一段符合要求的TOML代码,再将得到的对象赋值到目标位置——这样该对象会自动携带对应的格式元数据:
// 解析一段带目标格式的TOML,得到带元数据的对象 const formattedObj = TOML.parse(`fromObjectLiteralD.titles = ['D1', 'D2']`) // 替换原有对象 jsonParseToml.fromObjectLiteralD = formattedObj.fromObjectLiteralD
后续调用TOML.stringify()时,这个新增对象会沿用解析时的格式。
现象验证与测试代码
现象说明
TOML.parse()输出的JSON对象会保留原始TOML的格式信息:直接传入TOML.stringify()时,原始格式会被保留;但如果先把这个JSON序列化为字符串再解析回JSON(也就是净化操作),格式信息就会丢失。
原始TOML示例
# Tables defined in three different ways A,B,C: parsedFromTomlA.titles = ['A1', 'A2'] parsedFromTomlB.titles = [ 'B1', 'B2' ] [parsedFromTomlC] titles = ['C1', 'C2']
直接解析后序列化的输出
执行TOML.stringify(TOML.parse(toml))得到:
parsedFromTomlA.titles = ['A1', 'A2'] parsedFromTomlB.titles = [ 'B1', 'B2', ] fromObjectLiteralD.titles = [ 'D1', 'D2', ] [parsedFromTomlC] titles = ['C1', 'C2']
净化后序列化的输出
执行TOML.stringify(JSON.parse(JSON.stringify(TOML.parse(toml))))得到:
parsedFromTomlA.titles = [ 'A1', 'A2', ] parsedFromTomlB.titles = [ 'B1', 'B2', ] parsedFromTomlC.titles = [ 'C1', 'C2', ] fromObjectLiteralD.titles = [ 'D1', 'D2', ]
测试代码
var TOML = require("@ltd/j-toml") const toml = ` parsedFromTomlA.titles = ['A1', 'A2'] parsedFromTomlB.titles = [ 'B1', 'B2' ] [parsedFromTomlC] titles = ['C1', 'C2'] ` const jsonParseToml = TOML.parse(toml) // 添加对象字面量 jsonParseToml.fromObjectLiteralD = { titles: ['D1', 'D2'] } // 执行*净化*操作:转成字符串再解析回JSON const jsonParseJson = JSON.parse(JSON.stringify(jsonParseToml)) console.log('两个对象序列化后内容一致:') console.log('jsonParseToml', JSON.stringify(jsonParseToml, null, 4)) console.log('jsonParseJson', JSON.stringify(jsonParseJson, null, 4)) // 转回TOML格式 const tomlOutParseToml = TOML.stringify(jsonParseToml, {newline: '\n'}) const tomlOutParseJson = TOML.stringify(jsonParseJson, {newline: '\n'}) console.log('但TOML输出结果不同:') console.log('tomlOutParseToml', tomlOutParseToml) console.log('tomlOutParseJson', tomlOutParseJson)
内容的提问来源于stack exchange,提问作者Leftium
相关产品推荐
相关产品推荐

