我正在开发一种工具来在线创建Nassi-Shneiderman图表。 每个图表的模型只是一个对象文字,用无限可能的孩子存储所有内容。
然后会生成如下填充的视图:
现在,如果我想在第一个序列之后添加让我们说序列进入while循环,我就不得不在对象中添加一个子节点现有的两个孩子之间。默认情况下,对象属性的顺序不可编辑,而W3C表示不应该依赖属性的顺序,因为它可以区分浏览器。 我知道我可以将对象的顺序存储在数组中,但是我必须重写填充视图的递归循环等等。
我可以以某种方式操纵对象属性的顺序吗? 我不介意使用第三方库。
按顺序"顺序"我指的是使用for(prop in obj)
循环迭代对象属性的顺序。
这是我的数据结构/对象的一个示例:
{
"procedure": {
"id": "content",
"child": {
"154": {
"class": "sequence",
"text": "json manually created in code",
"id": 154,
"contenteditable": "true"
},
"155": {
"class": "while",
"id": 155,
"child": {
"157": {
"class": "while-condition",
"text": "while JSON from File imported",
"id": 157,
"contenteditable": "true"
},
"158": {
"class": "while-body",
"id": 158,
"child": {
"159": {
"class": "sequence",
"text": "Sequence in a while loop",
"id": 159,
"contenteditable": "true"
},
"160": {
"class": "while",
"id": 160,
"child": {
"161": {
"class": "while-condition",
"text": "while parentNode.Whatever != FALSE",
"id": 161,
"contenteditable": "true"
},
"162": {
"class": "while-body",
"id": 162,
"child": {
"163": {
"class": "sequence",
"text": "Sequence even deeper nested",
"id": "163",
"contenteditable": "true"
}
}
}
}
}
}
}
}
},
"156": {
"class": "sequence",
"text": "Finish Procedure",
"id": 156,
"contenteditable": "true"
}
}
}
}
答案 0 :(得分:2)
(ECMAScript 2015(“ES6”)更改内容:请参阅答案末尾的更新。)
对象属性没有顺序(在JavaScript和JSON中都没有)。 (更多信息如下。)要获得订单,您必须使用数组,而不是对象属性。您必须将结构调整为children: []
而不是child: {}
。然后,当然,在其中两个之间添加条目是使用splice
(spec | MDN)的问题。
关于对象属性顺序及其缺乏:
来自JSON website:
对象是一组无序名称/值对。
(我的重点)
在JavaScript中,未指定for-in
循环访问属性的顺序 - 请参阅规范的§12.6.4:
枚举属性的机制和顺序(第一个算法中的步骤6.a,第二个算法中的步骤7.a)未指定。
(我的重点)
因此,每个JavaScript引擎都可以做任何想做的事情。它可能会按照它们添加到对象的顺序访问它们(许多引擎似乎都这样做)。或按字母顺序排列。或者按照对它们的属性存储机制最方便的顺序排序,这很可能是一个哈希树,因此如果你不知道散列机制,看似随机。
同样,Object.keys
没有保证订单,所有规范都说如果引擎保证订单for-in
,那么Object.keys
必须遵循订购。但由于规范不要求引擎保证订单......
从ECMAScript 2015(ES6)开始,对象属性have order now:
- 让键成为新的空列表。
- 对于作为整数索引的 O 的每个自有属性键 P ,按升序数字索引顺序
- 添加 P 作为键的最后一个元素。
- 对于 O 的每个属性键 P ,它是一个String但不是整数索引,在属性创建顺序中
- 添加 P 作为键的最后一个元素。
- 对于作为符号的 O 的每个属性键 P ,在属性创建顺序中
- 添加 P 作为键的最后一个元素。
- 返回键。
醇>
...所以你确实可以通过操纵属性添加到对象的顺序来做到这一点。我不是建议你做它,但现在可以在兼容引擎上。