Manipulate Object literal:按特定顺序添加属性

时间:2015-03-13 07:53:32

标签: javascript json object properties

我正在开发一种工具来在线创建Nassi-Shneiderman图表。 每个图表的模型只是一个对象文字,用无限可能的孩子存储所有内容。

然后会生成如下填充的视图: View

现在,如果我想在第一个序列之后添加让我们说序列进入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"
            }
        }
    }
}

1 个答案:

答案 0 :(得分:2)

(ECMAScript 2015(“ES6”)更改内容:请参阅答案末尾的更新。)

对象属性没有顺序(在JavaScript和JSON中都没有)。 (更多信息如下。)要获得订单,您必须使用数组,而不是对象属性。您必须将结构调整为children: []而不是child: {}。然后,当然,在其中两个之间添加条目是使用splicespec | MDN)的问题。

关于对象属性顺序及其缺乏:

JSON

来自JSON website

  

对象是一组无序名称/值对。

(我的重点)

的JavaScript

在JavaScript中,未指定for-in循环访问属性的顺序 - 请参阅规范的§12.6.4

  

枚举属性的机制和顺序(第一个算法中的步骤6.a,第二个算法中的步骤7.a)未指定

(我的重点)

因此,每个JavaScript引擎都可以做任何想做的事情。它可能会按照它们添加到对象的顺序访问它们(许多引擎似乎都这样做)。或按字母顺序排列。或者按照对它们的属性存储机制最方便的顺序排序,这很可能是一个哈希树,因此如果你不知道散列机制,看似随机。

同样,Object.keys没有保证订单,所有规范都说如果引擎保证订单for-in,那么Object.keys必须遵循订购。但由于规范不要求引擎保证订单......


从ECMAScript 2015(ES6)开始,对象属性have order now

  
      
  1. 成为新的空列表。
  2.   
  3. 对于作为整数索引的 O 的每个自有属性键 P ,按升序数字索引顺序      
        
    • 添加 P 作为的最后一个元素。
    •   
  4.   
  5. 对于 O 的每个属性键 P ,它是一个String但不是整数索引,在属性创建顺序中      
        
    • 添加 P 作为的最后一个元素。
    •   
  6.   
  7. 对于作为符号的 O 的每个属性键 P ,在属性创建顺序中      
        
    • 添加 P 作为的最后一个元素。
    •   
  8.   
  9. 返回
  10.   

...所以你确实可以通过操纵属性添加到对象的顺序来做到这一点。我不是建议你它,但现在可以在兼容引擎上。