Если я создаю объект, как это:
var obj = {};
obj.prop1 = "Foo";
obj.prop2 = "Bar";
Будет ли результирующий объект всегда выглядеть так?
{ prop1 : "Foo", prop2 : "Bar" }
То есть свойства будут в том же порядке, в котором я их добавил?
javascript
object
mellowsoon
источник
источник
for-in
,Object.keys
) не должны поддерживать это (официально), но сейчас есть порядок. (Неофициально: Firefox, Chrome и Edge следуют указанному порядку даже в for-in и Object.keys, где они официально не обязаны: jsfiddle.net/arhbn3k2/1 )Ответы:
Порядок итераций для объектов соответствует определенному набору правил, начиная с ES2015, но он не всегда соответствует порядку вставки . Проще говоря, порядок итераций представляет собой комбинацию порядка вставки для строковых ключей и возрастающего порядка для числовых ключей:
Использование массива или
Map
объекта может быть лучшим способом для достижения этой цели.Map
разделяет некоторые сходстваObject
и гарантирует, что ключи будут повторяться в порядке вставки , без исключения:Как примечание, порядок свойств в объектах не был гарантирован до ES2015. Определение объекта из ECMAScript Third Edition (pdf) :
источник
ДА (для нецелых ключей).
Большинство браузеров повторяют свойства объекта следующим образом:
Некоторые старые браузеры объединяют категории # 1 и # 2, перебирая все ключи в порядке вставки. Если ваши ключи могут анализироваться как целые числа, лучше не полагаться на какой-либо определенный порядок итераций.
Текущие языковые спецификации (начиная с ES2015) порядок вставки сохраняется, за исключением случаев, когда ключи разбираются как целые числа (например, «7» или «99»), где поведение варьируется в разных браузерах. Например, Chrome / V8 не учитывает порядок вставки, когда ключи анализируются как числовые.
Спецификация старого языка (до ES2015) : Порядок итераций был технически не определен, но все основные браузеры соответствовали поведению ES2015.
Обратите внимание, что поведение ES2015 было хорошим примером языковой спецификации, обусловленной существующим поведением, а не наоборот. Чтобы получить более глубокое представление об этом образе мышления с обратной совместимостью, см. Http://code.google.com/p/v8/issues/detail?id=164 , ошибку Chrome, которая подробно описывает решения по разработке поведения порядка итерации Chrome , За один из (довольно самоуверенных) комментариев к этому сообщению об ошибке:
источник
createFragment
API уже полагается на это ... 🤔Порядок свойств в обычных объектах является сложным предметом в Javascript.
В то время как в ES5 порядок явно не указан, в некоторых случаях ES2015 имеет порядок. Дан следующий объект:
Это приводит к следующему порядку (в некоторых случаях):
Таким образом, есть три сегмента, которые могут изменить порядок вставки (как это было в примере). И целочисленные ключи вообще не придерживаются порядка вставки.
Вопрос в том, для каких методов этот заказ гарантирован в спецификации ES2015?
Следующие методы гарантируют указанный порядок:
Следующие методы / циклы гарантируют отсутствие порядка вообще:
Вывод: даже в ES2015 вы не должны полагаться на порядок свойств обычных объектов в Javascript. Это склонно к ошибкам. Используйте
Map
вместо этого.источник
На момент написания большинство браузеров возвращали свойства в том же порядке, в котором они были вставлены, но это явно не гарантированное поведение, поэтому на него не следует полагаться.
Спецификация ECMAScript используется, чтобы сказать:
Однако в ES2015 и более поздних нецелые ключи будут возвращены в порядке вставки.
источник
Весь этот ответ находится в контексте соответствия спецификациям, а не тому, что любой двигатель делает в определенный момент или исторически.
Как правило, нет
Фактический вопрос очень расплывчатый.
В каком контексте?
Ответ: это зависит от ряда факторов. В общем нет .
Иногда да
Вот где вы можете рассчитывать на порядок ключей свойства для простого
Objects
:Object.getOwnPropertyNames()
,Reflect.ownKeys()
,Object.getOwnPropertySymbols(O)
Во всех случаях эти методы включают не перечисляемые ключи свойств и ключи порядка, как указано
[[OwnPropertyKeys]]
(см. Ниже). Они отличаются по типу ключевых значений, которые они включают (String
и / илиSymbol
). В этом контекстеString
включены целочисленные значения.Object.getOwnPropertyNames(O)
Возвращает
O
собственныеString
свойства ключа ( имена свойств ).Reflect.ownKeys(O)
Возвращает
O
собственныеString
иSymbol
ключевые свойства.Object.getOwnPropertySymbols(O)
Возвращает
O
собственныеSymbol
свойства ключа[[OwnPropertyKeys]]
Порядок по существу: целочисленный
Strings
в порядке возрастания, нецелыйStrings
в порядке создания, символы в порядке создания. В зависимости от того, какая функция вызывает это, некоторые из этих типов могут быть не включены.Определенным языком является то, что ключи возвращаются в следующем порядке:
Map
Если вас интересуют упорядоченные карты, вам следует рассмотреть возможность использования
Map
типа, представленного в ES2015, вместо простогоObjects
.источник
В современных браузерах вы можете использовать
Map
структуру данных вместо объекта.Разработчик mozilla> Карта
источник
В ES2015 это так, но не то, что вы думаете
Порядок ключей в объекте не гарантировался до ES2015. Это было определено реализацией.
Однако, в ES2015 ин был указан. Как и многие другие вещи в JavaScript, это было сделано в целях совместимости и, как правило, отражало существующий неофициальный стандарт среди большинства движков JS (за исключением, вы знаете, кто).
Порядок определяется в спецификации в рамках абстрактной операции OrdinaryOwnPropertyKeys , которая лежит в основе всех методов итерации по собственным ключам объекта. Перефразируя, порядок выглядит следующим образом:
Все целочисленные индексные ключи (например
"1123"
,"55"
и т. Д.) В порядке возрастания номеров.Все строковые ключи, которые не являются целочисленными индексами, в порядке создания (самые старые-первые).
Все символьные клавиши в порядке создания (самые старые-первые).
Глупо говорить, что порядок ненадежен - он надежен, просто, вероятно, это не то, что вам нужно, и современные браузеры правильно его реализуют.
Некоторые исключения включают методы перечисления унаследованных ключей, такие как
for .. in
цикл.for .. in
Цикл не гарантирует порядок в соответствии со спецификацией.источник
Начиная с ES2015, порядок свойств гарантирован для определенных методов, которые перебирают свойства. но не другие . К сожалению, методы, порядок которых не гарантирован, обычно используются чаще всего:
Object.keys
,Object.values
,Object.entries
for..in
петлиJSON.stringify
Но, начиная с ES2020, порядок свойств для этих ранее ненадежных методов будет гарантирован, что спецификация будет повторяться таким же детерминированным образом, как и другие, из-за готового предложения: механика for-in .
Как и в случае с методами, которые имеют гарантированный порядок итераций (например,
Reflect.ownKeys
иObject.getOwnPropertyNames
), ранее неуказанные методы также будут выполнять итерацию в следующем порядке:Это то, что в значительной степени каждая реализация уже делает (и делала в течение многих лет), но новое предложение сделало его официальным.
Хотя текущая спецификация оставляет для… в итерационном порядке « почти полностью неопределенные , реальные движки имеют тенденцию быть более последовательными:»
Поскольку каждая реализация уже предсказуемо перебирает свойства, ее можно поместить в спецификацию, не нарушая обратной совместимости.
Есть несколько странных случаев, с которыми реализации в настоящее время не согласуются, и в таких случаях результирующий порядок будет по-прежнему не определен. Для гарантированного заказа недвижимости :
источник
Как уже говорили другие, у вас нет никаких гарантий относительно порядка, когда вы перебираете свойства объекта. Если вам нужен упорядоченный список из нескольких полей, я предложил создать массив объектов.
Таким образом, вы можете использовать обычный цикл for и иметь порядок вставки. Затем вы можете использовать метод сортировки Array, чтобы отсортировать его в новый массив, если это необходимо.
источник
Просто выяснил это трудным путем.
Используя React с Redux, контейнер состояний, ключи которого я хочу просмотреть для генерации дочерних элементов, обновляется каждый раз при изменении хранилища (согласно концепции неизменяемости Redux).
Таким образом, для того, чтобы взять,
Object.keys(valueFromStore)
я использовалObject.keys(valueFromStore).sort()
, так что у меня по крайней мере теперь есть алфавитный порядок для ключей.источник
Из стандарта JSON :
(акцент мой).
Итак, нет, вы не можете гарантировать заказ.
источник