JavaScript 保证对象属性顺序吗?

发布于 2024-10-29 17:42:54 字数 226 浏览 1 评论 0 原文

如果我创建一个像这样的对象:

var obj = {};
obj.prop1 = "Foo";
obj.prop2 = "Bar";

生成的对象总是看起来像这样吗?

{ prop1 : "Foo", prop2 : "Bar" }

也就是说,这些属性的顺序是否与我添加它们的顺序相同?

If I create an object like this:

var obj = {};
obj.prop1 = "Foo";
obj.prop2 = "Bar";

Will the resulting object always look like this?

{ prop1 : "Foo", prop2 : "Bar" }

That is, will the properties be in the same order that I added them?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

久而酒知 2024-11-05 17:42:54

自 ES2015 以来,对象的迭代顺序遵循一组特定规则,但它并不(始终)遵循插入顺序。简而言之,迭代顺序是字符串键的插入顺序和类似数字的键的升序的组合:

// key order: 1, foo, bar
const obj = { "foo": "foo", "1": "1", "bar": "bar" }

使用数组或 Map 对象 可能是实现此目的的更好方法。 MapObject保证按插入顺序迭代键,无一例外:

Map 中的键是有序的,而添加到对象中的键则不是有序的。因此,当迭代它时,Map 对象按插入顺序返回键。 (请注意,在 ECMAScript 2015 规范中,对象确实保留了字符串和符号键的创建顺序,因此仅使用 ie 字符串键遍历对象将按照插入顺序生成键)

请注意,对象中的属性顺序不能保证全部在 ES2015 之前。对象的定义来自 ECMAScript 第三版 (pdf)

4.3.3 对象

一个对象是一个成员
类型对象。 它是一个无序的属性集合,每个属性
包含原始值、对象或
功能。一个函数存储在
对象的属性称为
方法。

The iteration order for objects follows a certain set of rules since ES2015, but it does not (always) follow the insertion order. Simply put, the iteration order is a combination of the insertion order for strings keys, and ascending order for number-like keys:

// key order: 1, foo, bar
const obj = { "foo": "foo", "1": "1", "bar": "bar" }

Using an array or a Map object can be a better way to achieve this. Map shares some similarities with Object and guarantees the keys to be iterated in order of insertion, without exception:

The keys in Map are ordered while keys added to object are not. Thus, when iterating over it, a Map object returns keys in order of insertion. (Note that in the ECMAScript 2015 spec objects do preserve creation order for string and Symbol keys, so traversal of an object with ie only string keys would yield keys in order of insertion)

As a note, properties order in objects weren’t guaranteed at all before ES2015. Definition of an Object from ECMAScript Third Edition (pdf):

4.3.3 Object

An object is a member of the
type Object. It is an unordered collection of properties each of which
contains a primitive value, object, or
function. A function stored in a
property of an object is called a
method.

梦屿孤独相伴 2024-11-05 17:42:54

是(但并不总是插入顺序)。

大多数浏览器将对象属性迭代为:

  1. 按升序排列的正整数键(以及解析为整数的“1”等字符串)
  2. 按插入顺序排列的字符串键(ES2015 保证)这个和所有浏览器都符合)
  3. 符号名称,按插入顺序(ES2015保证这个和所有浏览器都符合)

一些旧的浏览器组合类别#1和#2,按插入顺序迭代所有键。如果您的键可能解析为整数,则最好不要依赖任何特定的迭代顺序。

当前语言规范(自 ES2015 起) 插入顺序将被保留,但解析为正整数(例如“7”或“99”)的键除外,这种情况下浏览器的行为会有所不同。例如,当键解析为数字时,Chrome/V8 不考虑插入顺序。

旧语言规范(ES2015 之前):迭代顺序在技术上未定义,但所有主要浏览器都遵守 ES2015 行为。

请注意,ES2015 行为是语言规范由现有行为驱动的一个很好的例子,而不是相反。要更深入地了解向后兼容的心态,请参阅 http:// code.google.com/p/v8/issues/detail?id=164,一个 Chrome 错误,详细介绍了 Chrome 迭代顺序行为背后的设计决策。
根据对该错误报告的评论之一(相当固执己见):

标准始终遵循实现,这就是 XHR 的由来,Google 通过实现 Gears 然后采用等效的 HTML5 功能来实现同样的目的。正确的解决方法是让 ECMA 正式将事实上的标准行为纳入下一版本的规范中。

YES (but not always insertion order).

Most Browsers iterate object properties as:

  1. Positive integer keys in ascending order (and strings like "1" that parse as ints)
  2. String keys, in insertion order (ES2015 guarantees this and all browsers comply)
  3. Symbol names, in insertion order (ES2015 guarantees this and all browsers comply)

Some older browsers combine categories #1 and #2, iterating all keys in insertion order. If your keys might parse as integers, it's best not to rely on any specific iteration order.

Current Language Spec (since ES2015) insertion order is preserved, except in the case of keys that parse as positive integers (eg "7" or "99"), where behavior varies between browsers. For example, Chrome/V8 does not respect insertion order when the keys are parse as numeric.

Old Language Spec (before ES2015): Iteration order was technically undefined, but all major browsers complied with the ES2015 behavior.

Note that the ES2015 behavior was a good example of the language spec being driven by existing behavior, and not the other way round. To get a deeper sense of that backwards-compatibility mindset, see http://code.google.com/p/v8/issues/detail?id=164, a Chrome bug that covers in detail the design decisions behind Chrome's iteration order behavior.
Per one of the (rather opinionated) comments on that bug report:

Standards always follow implementations, that's where XHR came from, and Google does the same thing by implementing Gears and then embracing equivalent HTML5 functionality. The right fix is to have ECMA formally incorporate the de-facto standard behavior into the next rev of the spec.

生活了然无味 2024-11-05 17:42:54

普通对象中的属性顺序是 JavaScript 中的一个复杂主题。

虽然在 ES5 中明确没有指定顺序,但 ES2015 在某些情况下定义了顺序,并且此后对规范的连续更改越来越多地定义了顺序(甚至,从 ES2020 开始,for-in 循环的顺序)。给出以下对象:

const o = Object.create(null, {
  m: {value: function() {}, enumerable: true},
  "2": {value: "2", enumerable: true},
  "b": {value: "b", enumerable: true},
  0: {value: 0, enumerable: true},
  [Symbol()]: {value: "sym", enumerable: true},
  "1": {value: "1", enumerable: true},
  "a": {value: "a", enumerable: true},
});

这会产生以下顺序(在某些情况下):

Object {
  0: 0,
  1: "1",
  2: "2",
  b: "b",
  a: "a",
  m: function() {},
  Symbol(): "sym"
}

“own”的顺序(非继承)属性 为:

  1. 升序的正整数类键
  2. 插入顺序的字符串键
  3. 插入顺序的符号

因此,存在三个段,它们可能会改变插入顺序(如示例中所示)。并且类似正整数的键根本不遵守插入顺序。

在 ES2015 中,只有某些方法遵循以下顺序:

  • Object.assign
  • Object.defineProperties
  • Object.getOwnPropertyNames
  • Object.getOwnPropertySymbols
  • Reflect.ownKeys
  • JSON.parse
  • JSON.stringify

从 ES2020 开始,所有其他方法都这样做(有些在 ES2015 和 ES2020 之间的规范中,其他在 ES2020 中) ),其中包括:

  • Object.keys、Object.entries、Object.values、...
  • for..in

最难确定的是 for-in,因为它独特地包含继承的属性。 已在 ES2020 中完成(除边缘情况外)。链接(现已完成)提案中的以下列表提供了未指定顺序的边缘情况:

  • 正在迭代的对象或其原​​型链中的任何内容都不是代理、类型化数组、模块命名空间对象或主机外来对象。
  • 在迭代过程中,对象或其原​​型链中的任何内容都没有改变其原型。
  • 该对象或其原​​型链中的任何内容都没有在迭代期间删除的属性。
  • 对象的原型链中没有任何内容在迭代期间添加了属性。
  • 对象的属性或其原型链中的任何内容在迭代期间都不会发生可枚举性变化。
  • 没有不可枚举的属性会影响可枚举的属性。

结论:即使在 ES2015 中,您也不应该依赖 JavaScript 中普通对象的属性顺序。它很容易出错。如果您需要有序命名对,请使用 Map<相反, /code> 纯粹使用插入顺序。如果您只需要顺序,请使用数组或 设置(也使用纯粹的插入顺序)。

Property order in normal Objects is a complex subject in JavaScript.

While in ES5 explicitly no order has been specified, ES2015 defined an order in certain cases, and successive changes to the specification since have increasingly defined the order (even, as of ES2020, the for-in loop's order). Given is the following object:

const o = Object.create(null, {
  m: {value: function() {}, enumerable: true},
  "2": {value: "2", enumerable: true},
  "b": {value: "b", enumerable: true},
  0: {value: 0, enumerable: true},
  [Symbol()]: {value: "sym", enumerable: true},
  "1": {value: "1", enumerable: true},
  "a": {value: "a", enumerable: true},
});

This results in the following order (in certain cases):

Object {
  0: 0,
  1: "1",
  2: "2",
  b: "b",
  a: "a",
  m: function() {},
  Symbol(): "sym"
}

The order for "own" (non-inherited) properties is:

  1. Positive integer-like keys in ascending order
  2. String keys in insertion order
  3. Symbols in insertion order

Thus, there are three segments, which may alter the insertion order (as happened in the example). And positive integer-like keys don't stick to the insertion order at all.

In ES2015, only certain methods followed the order:

  • Object.assign
  • Object.defineProperties
  • Object.getOwnPropertyNames
  • Object.getOwnPropertySymbols
  • Reflect.ownKeys
  • JSON.parse
  • JSON.stringify

As of ES2020, all others do (some in specs between ES2015 and ES2020, others in ES2020), which includes:

  • Object.keys, Object.entries, Object.values, ...
  • for..in

The most difficult to nail down was for-in because, uniquely, it includes inherited properties. That was done (in all but edge cases) in ES2020. The following list from the linked (now completed) proposal provides the edge cases where the order is not specified:

  • Neither the object being iterated nor anything in its prototype chain is a proxy, typed array, module namespace object, or host exotic object.
  • Neither the object nor anything in its prototype chain has its prototype change during iteration.
  • Neither the object nor anything in its prototype chain has a property deleted during iteration.
  • Nothing in the object's prototype chain has a property added during iteration.
  • No property of the object or anything in its prototype chain has its enumerability change during iteration.
  • No non-enumerable property shadows an enumerable one.

Conclusion: Even in ES2015 you shouldn't rely on the property order of normal objects in JavaScript. It is prone to errors. If you need ordered named pairs, use Map instead, which purely uses insertion order. If you just need order, use an array or Set (which also uses purely insertion order).

无法回应 2024-11-05 17:42:54

在撰写本文时,大多数浏览器确实按照插入的顺序返回属性,但明确不能保证其行为,因此不应依赖它。

ECMAScript 规范过去常说:

枚举属性的机制和顺序......未指定。

但是在 ES2015 及更高版本中,非整数键将按插入顺序返回。

At the time of writing, most browsers did return properties in the same order as they were inserted, but it was explicitly not guaranteed behaviour so shouldn't have been relied upon.

The ECMAScript specification used to say:

The mechanics and order of enumerating the properties ... is not specified.

However in ES2015 and later non-integer keys will be returned in insertion order.

可遇━不可求 2024-11-05 17:42:54

整个答案是在规范合规性的背景下进行的,而不是任何引擎在特定时刻或历史上所做的事情。

一般来说,没有

实际的问题是非常模糊的。

属性的顺序是否与我添加它们的顺序相同

在什么上下文中?

答案是:这取决于许多因素。一般来说,

有时,是的

,在这里您可以依靠普通对象的属性键顺序:

  • ES2015兼容引擎
  • 自己的属性
  • Object.getOwnPropertyNames()Reflect.ownKeys() , Object.getOwnPropertySymbols(O)

在所有情况下,这些方法都包含由 [[OwnPropertyKeys]] 指定的不可枚举属性键和顺序键(见下文) )。它们的不同之处在于所包含的键值类型(String 和/或 Symbol)。在此上下文中,String 包括整数值。

Object.getOwnPropertyNames(O)< /a>

返回 O 自己的 String 键控属性(属性名称)。

Reflect.ownKeys(O)< /a>

返回 O 自己的 StringSymbol 键控属性。

Object.getOwnPropertySymbols(O)< /a>

返回 O 自己的 Symbol 键控属性。

[[OwnPropertyKeys]]

顺序本质上是:类整数 String 按升序排列,非类整数 String 按创建顺序排列, 按创建顺序排列的符号。根据调用此函数的函数,可能不包含其中某些类型。

具体语言是,key按照以下顺序返回:

  • ...O [正在迭代的对象] 的每个自己的属性键 P 是一个整数索引,按数字索引升序排列

  • ...O 的每个自己的属性键 P 是一个字符串,但不是整数索引,按照属性创建顺序

    < /里>

  • ...O 的每个自己的属性键 P 是一个符号,按照属性创建顺序

  • Map

    如果您对有序地图感兴趣,您应该考虑使用 ES2015 中引入的 Map 类型,而不是普通的 Objects

    This whole answer is in the context of spec compliance, not what any engine does at a particular moment or historically.

    Generally, no

    The actual question is very vague.

    will the properties be in the same order that I added them

    In what context?

    The answer is: it depends on a number of factors. In general, no.

    Sometimes, yes

    Here is where you can count on property key order for plain Objects:

    • ES2015 compliant engine
    • Own properties
    • Object.getOwnPropertyNames(), Reflect.ownKeys(), Object.getOwnPropertySymbols(O)

    In all cases these methods include non-enumerable property keys and order keys as specified by [[OwnPropertyKeys]] (see below). They differ in the type of key values they include (String and / or Symbol). In this context String includes integer values.

    Object.getOwnPropertyNames(O)

    Returns O's own String-keyed properties (property names).

    Reflect.ownKeys(O)

    Returns O's own String- and Symbol-keyed properties.

    Object.getOwnPropertySymbols(O)

    Returns O's own Symbol-keyed properties.

    [[OwnPropertyKeys]]

    The order is essentially: integer-like Strings in ascending order, non-integer-like Strings in creation order, Symbols in creation order. Depending which function invokes this, some of these types may not be included.

    The specific language is that keys are returned in the following order:

    1. ... each own property key P of O [the object being iterated] that is an integer index, in ascending numeric index order

    2. ... each own property key P of O that is a String but is not an integer index, in property creation order

    3. ... each own property key P of O that is a Symbol, in property creation order

    Map

    If you're interested in ordered maps you should consider using the Map type introduced in ES2015 instead of plain Objects.

    看海 2024-11-05 17:42:54

    从 ES2015 开始,某些迭代属性的方法可以保证属性顺序。 但不是其他。不幸的是,不保证顺序的方法通常是最常用的:

    • Object.keysObject.valuesObject.entries >
    • for..in 循环
    • JSON.stringify

    但是,从 ES2020 开始,这些以前不可信方法的属性顺序由由于 将以与其他规范相同的确定性方式进行迭代rel="noreferrer">完成提案:for-in 机制

    就像具有保证迭代顺序的方法(例如 Reflect.ownKeys 和 Object.getOwnPropertyNames )一样,之前未指定的方法也将按以下顺序迭代

    • :数组键,按升序数字顺序
    • 所有其他非符号键,按插入顺序
    • 符号键,按插入顺序

    这几乎是每个实现都已经做的事情(并且已经做了很多年),但新提案已将其正式化。

    尽管当前规范留下了 for..in 迭代顺序“几乎完全未指定,真实的引擎往往更加一致:”

    ECMA-262 缺乏特异性并不能反映现实。在多年前的讨论中,实现者观察到 for-in 的行为存在一些限制,任何想要在网络上运行代码的人都需要遵循这些限制。

    因为每个实现都已经可预测地迭代属性,所以可以将其放入规范中而不会破坏向后兼容性。


    有一些奇怪的情况,目前的实现不同意,在这种情况下,结果顺序将继续未指定。为了保证属性顺序有保证

    正在迭代的对象及其原型链中的任何内容都不是代理、类型化数组、模块命名空间对象或主机外来对象。

    在迭代过程中,对象及其原型链中的任何内容都不会改变其原型。

    该对象及其原型链中的任何内容都没有在迭代期间删除的属性。

    对象的原型链中没有任何内容在迭代期间添加了属性。

    在迭代过程中,对象的属性或其原型链中的任何内容都不会发生可枚举性变化。

    没有不可枚举的属性会影响可枚举的属性。

    As of ES2015, property order is guaranteed for certain methods that iterate over properties. but not others. Unfortunately, the methods which are not guaranteed to have an order are generally the most often used:

    • Object.keys, Object.values, Object.entries
    • for..in loops
    • JSON.stringify

    But, as of ES2020, property order for these previously untrustworthy methods will be guaranteed by the specification to be iterated over in the same deterministic manner as the others, due to to the finished proposal: for-in mechanics.

    Just like with the methods which have a guaranteed iteration order (like Reflect.ownKeys and Object.getOwnPropertyNames), the previously-unspecified methods will also iterate in the following order:

    • Numeric array keys, in ascending numeric order
    • All other non-Symbol keys, in insertion order
    • Symbol keys, in insertion order

    This is what pretty much every implementation does already (and has done for many years), but the new proposal has made it official.

    Although the current specification leaves for..in iteration order "almost totally unspecified, real engines tend to be more consistent:"

    The lack of specificity in ECMA-262 does not reflect reality. In discussion going back years, implementors have observed that there are some constraints on the behavior of for-in which anyone who wants to run code on the web needs to follow.

    Because every implementation already iterates over properties predictably, it can be put into the specification without breaking backwards compatibility.


    There are a few weird cases which implementations currently do not agree on, and in such cases, the resulting order will continue be unspecified. For property order to be guaranteed:

    Neither the object being iterated nor anything in its prototype chain is a proxy, typed array, module namespace object, or host exotic object.

    Neither the object nor anything in its prototype chain has its prototype change during iteration.

    Neither the object nor anything in its prototype chain has a property deleted during iteration.

    Nothing in the object's prototype chain has a property added during iteration.

    No property of the object or anything in its prototype chain has its enumerability change during iteration.

    No non-enumerable property shadows an enumerable one.

    肩上的翅膀 2024-11-05 17:42:54

    在现代浏览器中,您可以使用 Map 数据结构而不是对象。

    开发者 mozilla >地图

    Map 对象可以按插入顺序迭代其元素...

    In modern browsers you can use the Map data structure instead of a object.

    Developer mozilla > Map

    A Map object can iterate its elements in insertion order...

    君勿笑 2024-11-05 17:42:54

    在 ES2015 中,确实如此,但并不像您想象的那样

    。直到 ES2015 才保证对象中键的顺序。它是由实现定义的。

    然而,在 ES2015 中它被指定了。与 JavaScript 中的许多事情一样,这样做是出于兼容性目的,并且通常反映了大多数 JS 引擎中现有的非官方标准(you-know-who 是一个例外)。

    该顺序在规范中的抽​​象操作 下定义OrdinaryOwnPropertyKeys,它支持迭代对象自己的键的所有方法。解释一下,顺序如下:

    1. 所有整数索引键(例如“1123”“55”等)数字升序。

    2. 所有不是整数索引的字符串键,按创建顺序(最旧的在前)。

    3. 所有符号键,按创建顺序(最旧的在前)。

    说这个顺序不可靠是愚蠢的——它是可靠的,只是可能不是你想要的,而现代浏览器正确地实现了这个顺序。

    一些例外情况包括枚举继承键的方法,例如 for .. in 循环,它不保证按照规范的顺序。

    In ES2015, it does, but not to what you might think

    The order of keys in an object wasn't guaranteed until ES2015. It was implementation-defined.

    However, in ES2015 it was specified. Like many things in JavaScript, this was done for compatibility purposes and generally reflected an existing unofficial standard among most JS engines (with you-know-who being an exception).

    The order is defined in the spec, under the abstract operation OrdinaryOwnPropertyKeys, which underpins all methods of iterating over an object's own keys. Paraphrased, the order is as follows:

    1. All integer index keys (stuff like "1123", "55", etc) in ascending numeric order.

    2. All string keys which are not integer indices, in order of creation (oldest-first).

    3. All symbol keys, in order of creation (oldest-first).

    It's silly to say that the order is unreliable - it is reliable, it's just probably not what you want, and modern browsers implement this order correctly.

    Some exceptions include methods of enumerating inherited keys, such as the for .. in loop, that doesn't guarantee order according to the specification.

    凌乱心跳 2024-11-05 17:42:54

    正如其他人所说,当您迭代对象的属性时,您无法保证顺序。如果您需要多个字段的有序列表,我建议创建一个对象数组。

    var myarr = [{somfield1: 'x', somefield2: 'y'},
    {somfield1: 'a', somefield2: 'b'},
    {somfield1: 'i', somefield2: 'j'}];
    

    这样您就可以使用常规的 for 循环并获得插入顺序。如果需要,您可以使用数组排序方法将其排序到新数组中。

    As others have stated, you have no guarantee as to the order when you iterate over the properties of an object. If you need an ordered list of multiple fields I suggested creating an array of objects.

    var myarr = [{somfield1: 'x', somefield2: 'y'},
    {somfield1: 'a', somefield2: 'b'},
    {somfield1: 'i', somefield2: 'j'}];
    

    This way you can use a regular for loop and have the insert order. You could then use the Array sort method to sort this into a new array if needed.

    分開簡單 2024-11-05 17:42:54

    对象和 MAP 之间的主要区别(以示例为例):

    它是循环中的迭代顺序,在 Map 中它遵循创建时设置的顺序,而在 OBJECT 中则不然。

    看:
    对象

    const obj = {};
    obj.prop1 = "Foo";
    obj.prop2 = "Bar";
    obj['1'] = "day";
    console.log(obj)
    
    **OUTPUT: {1: "day", prop1: "Foo", prop2: "Bar"}**
    

    地图

        const myMap = new Map()
        // setting the values
        myMap.set("foo", "value associated with 'a string'")
        myMap.set("Bar", 'value associated with keyObj')
        myMap.set("1", 'value associated with keyFunc')
    
    OUTPUT:
    **1.    ▶0: Array[2]
    1.   0: "foo"
    2.   1: "value associated with 'a string'"
    2.  ▶1: Array[2]
    1.   0: "Bar"
    2.   1: "value associated with keyObj"
    3.  ▶2: Array[2]
    1.   0: "1"
    2.   1: "value associated with keyFunc"**
    

    Major Difference between Object and MAP with Example :

    it's Order of iteration in loop, In Map it follows the order as it was set while creation whereas in OBJECT does not.

    SEE:
    OBJECT

    const obj = {};
    obj.prop1 = "Foo";
    obj.prop2 = "Bar";
    obj['1'] = "day";
    console.log(obj)
    
    **OUTPUT: {1: "day", prop1: "Foo", prop2: "Bar"}**
    

    MAP

        const myMap = new Map()
        // setting the values
        myMap.set("foo", "value associated with 'a string'")
        myMap.set("Bar", 'value associated with keyObj')
        myMap.set("1", 'value associated with keyFunc')
    
    OUTPUT:
    **1.    ▶0: Array[2]
    1.   0: "foo"
    2.   1: "value associated with 'a string'"
    2.  ▶1: Array[2]
    1.   0: "Bar"
    2.   1: "value associated with keyObj"
    3.  ▶2: Array[2]
    1.   0: "1"
    2.   1: "value associated with keyFunc"**
    
    听你说爱我 2024-11-05 17:42:54

    刚刚发现这一点很困难。

    将 React 与 Redux 结合使用,每次存储更改时,我想要遍历其键以生成子项的状态容器都会刷新(根据 Redux 的不变性概念)。

    因此,为了获取Object.keys(valueFromStore),我使用了Object.keys(valueFromStore).sort(),这样我至少现在有了按字母顺序排列的钥匙。

    Just found this out the hard way.

    Using React with Redux, the state container of which's keys I want to traverse in order to generate children is refreshed everytime the store is changed (as per Redux's immutability concepts).

    Thus, in order to take Object.keys(valueFromStore) I used Object.keys(valueFromStore).sort(), so that I at least now have an alphabetical order for the keys.

    绮筵 2024-11-05 17:42:54

    对于 100% 故障安全的解决方案,您可以使用嵌套对象并执行如下操作:

    const obj = {};
    obj.prop1 = {content: "Foo", index: 0};
    obj.prop2 = {content: "Bar", index: 1};
    
    for (let i = 0; i < Object.keys(obj).length; i++)
    for (const prop in obj) {
        if (obj[prop].index == i) {
            console.log(obj[prop].content);
            break;
        }
    }
    

    For a 100% fail-safe solution you could use nested objects and do something like this:

    const obj = {};
    obj.prop1 = {content: "Foo", index: 0};
    obj.prop2 = {content: "Bar", index: 1};
    
    for (let i = 0; i < Object.keys(obj).length; i++)
    for (const prop in obj) {
        if (obj[prop].index == i) {
            console.log(obj[prop].content);
            break;
        }
    }
    
    勿忘初心 2024-11-05 17:42:54

    实际上,它并不能保证顺序,但最有可能的是,它通过插入项目来排序,但在某些情况下顺序很容易发生变化。例如,如果您使用 Object.键和对象。值,它们的结果在第一顺序上并不相同。 保存顺序的可能

    解决方案是保存键并使用这些键以第一顺序访问对象。

    像这样的东西:

    MergeFlatedObjValue(obj){
      const myJSONString = JSON.stringify(obj);
      const regexp = /(?<!:)("[\w.]+")/g;
    let matches = myJSONString.matchAll(regexp);
    var MergeFlatedObjValue="";   
    for (const match of matches) {
      var matched=match[0];
       matched=matched.replace(/['"]+/g, '');
      MergeFlatedObjValue+=obj[matched]+"#";
    
    }
      return MergeFlatedObjValue;
    
      }
    

    Actually, it doesn't guarantee order, but most likely, it orders by inserting items, but in some cases the order is change prone .For instance, if you use Object. Keys and Object. Values, the results of them aren't the same in first order. Likely

    A solution to save order is to save keys and use those keys to access the object in the first order.

    Something like this:

    MergeFlatedObjValue(obj){
      const myJSONString = JSON.stringify(obj);
      const regexp = /(?<!:)("[\w.]+")/g;
    let matches = myJSONString.matchAll(regexp);
    var MergeFlatedObjValue="";   
    for (const match of matches) {
      var matched=match[0];
       matched=matched.replace(/['"]+/g, '');
      MergeFlatedObjValue+=obj[matched]+"#";
    
    }
      return MergeFlatedObjValue;
    
      }
    
    儭儭莪哋寶赑 2024-11-05 17:42:54

    实际的键顺序可能与插入顺序不同:

    console.log({ 5: 5, 2: 2 })
    

    结果是:

    { '2': 2, '5': 5 }
    

    所以不要依赖插入顺序。

    The actual key order can be different from the insertion order:

    console.log({ 5: 5, 2: 2 })
    

    And the result is:

    { '2': 2, '5': 5 }
    

    So don't rely on the insertion order.

    你如我软肋 2024-11-05 17:42:54

    编辑:下面的帖子只是开发者工具显示问题。正如@Bergi 所指出的,迭代顺序如其他答案中所述。我把它留在这里以防其他人发现同样的陷阱。作为记录,我的代码使用 Vite 进行编译,"react": "^18.3.1",并且我在 chrome 和 Firefox 中对此进行了测试。

    我的一些依赖属性顺序的代码刚刚崩溃了。今天我做了测试,发现它们现在的顺序如下:

    1. 数字
    2. 大写,字母顺序
    3. 小写,字母顺序

    因此,在我插入排序后的属性后,它们会恢复到这个顺序。这适用于 Object.fromEntries 和带括号的插入。以下代码:

    let test = {}
    test["b"] = "insert order 1"
    test["a"] = "insert order 2"
    test[1] = "insert order 3"
    test["B"] = "insert order 4"
    test["A"] = "insert order 5"
    test["C"] = "insert order 6"
    console.log(test)
    

    打印此内容:

    新对象属性排序

    Edit: the below post was only a developer tools display issue. As pointed out by @Bergi, the iteration order is as described in other answers. I leave it here in case others find the same pitfall. For the records, my code compiles with Vite, "react": "^18.3.1", and I tested this in both chrome and Firefox.

    Some of my code relying on the order of properties just broke. Today I made tests and found that they are now ordered like this:

    1. Numbers
    2. Caps, alphabetical order
    3. Lowercase, alphabetical order

    Hence, after I insert my sorted properties, they are put back to this order. This holds with Object.fromEntries and with insertion with brackets. The following code:

    let test = {}
    test["b"] = "insert order 1"
    test["a"] = "insert order 2"
    test[1] = "insert order 3"
    test["B"] = "insert order 4"
    test["A"] = "insert order 5"
    test["C"] = "insert order 6"
    console.log(test)
    

    Prints this:

    new object properties ordering

    夜空下最亮的亮点 2024-11-05 17:42:54

    来自 JSON 标准

    对象是零个或多个名称/值对的无序集合,其中名称是字符串,值是字符串、数字、布尔值、null、对象或数组。< /p>

    (强调我的)。

    所以,不,你不能保证订单。

    From the JSON standard:

    An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array.

    (emphasis mine).

    So, no you can't guarantee the order.

    ~没有更多了~
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文