操作 Object 文字:按一定顺序添加 属性

Manipulate Object literal: add property in certain order

我正在开发一种在线创建 Nassi-Shneiderman 图表的工具。 每个图表的模型只是一个 object 文字,以无限可能的方式存储所有内容 children.

这会导致填充的视图如下所示:

现在,如果我想在第一个 sequence 之后将 sequence 添加到 while 循环中,我必须以某种方式添加child 到object 两者之间存在children。 object 属性的顺序在默认情况下是不可编辑的,W3C 表示不应该依赖属性的顺序,因为它可以区分浏览器。 我知道我可以将 object 的顺序存储在一个数组中,但是我必须重写填充视图的递归循环等等..

我能否以某种方式操纵 object 的属性顺序? 我不介意使用第 3 方库。

"order" 我的意思是 object 的属性使用 for(prop in obj) 循环进行迭代的顺序。

这是我的数据示例 structure/object:

{
    "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"
            }
        }
    }
}

(ECMAScript 2015 ("ES6") 改变了一些东西:请参阅答案末尾的更新。)

对象属性没有顺序(在 JavaScript 和 JSON 中都没有)。 (下面有更多内容。)要有顺序,您必须使用数组,而不是对象属性。您必须调整结构以使用 children: [] 而不是 child: {}。然后,当然,在他们两个之间添加一个条目就是使用 splice (spec | MDN).

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

JSON

来自JSON website:

An object is an unordered set of name/value pairs.

(我的重点)

JavaScript

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

The mechanics and order of enumerating the properties (step 6.a in the first algorithm, step 7.a in the second) is not specified.

(我的重点)

因此每个 JavaScript 引擎都可以为所欲为。它可能会按照将它们添加到对象的顺序访问它们(许多引擎似乎都这样做)。或者按字母顺序排列。或者根据最方便的 属性 存储机制来排序,这很可能是哈希树,因此如果您不知道哈希机制,则看起来是随机的。

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


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

  1. Let keys be a new empty List.
  2. For each own property key P of O that is an integer index, in ascending numeric index order
    • Add P as the last element of keys.
  3. For each own property key P of O that is a String but is not an integer index, in property creation order
    • Add P as the last element of keys.
  4. For each own property key P of O that is a Symbol, in property creation order
    • Add P as the last element of keys.
  5. Return keys.

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