Недавно я написал универсальную функцию для управления этим для вас, если вы хотите его использовать.
/**
* Sorts an object into an order
*
* @require jQuery
*
* @param object Our JSON object to sort
* @param type Only alphabetical at the moment
* @param identifier The array or object key to sort by
* @param order Ascending or Descending
*
* @returns Array
*/
function sortItems(object, type, identifier, order){
var returnedArray = [];
var emptiesArray = []; // An array for all of our empty cans
// Convert the given object to an array
$.each(object, function(key, object){
// Store all of our empty cans in their own array
// Store all other objects in our returned array
object[identifier] == null ? emptiesArray.push(object) : returnedArray.push(object);
});
// Sort the array based on the type given
switch(type){
case 'alphabetical':
returnedArray.sort(function(a, b){
return(a[identifier] == b[identifier]) ? 0 : (
// Sort ascending or descending based on order given
order == 'asc' ? a[identifier] > b[identifier] : a[identifier] < b[identifier]
) ? 1 : -1;
});
break;
default:
}
// Return our sorted array along with the empties at the bottom depending on sort order
return order == 'asc' ? returnedArray.concat(emptiesArray) : emptiesArray.concat(returnedArray);
}
Нет, порядок свойств объектов не гарантируется в JavaScript; вам нужно использовать Array
.
Определение объекта из ECMAScript Third Edition (pdf) :
4.3.3 Объект
Объект является членом типа Object. Это неупорядоченный набор свойств, каждый из которых содержит примитивное значение, объект или функцию. Функция, хранящаяся в свойстве объекта, называется методом.
Поскольку ECMAScript 2015, использование объекта
Map
может быть альтернативой. AMap
разделяет некоторые сходства сObject
и гарантирует порядок ключей :Карта выполняет итерацию своих элементов в порядке размещения, тогда как порядок итерации не указан для объектов.
Во время записи большинство браузеров возвращали свойства в том же порядке, в каком они были вставлены, но это явно не гарантированное поведение, поэтому на него не следует полагаться.
Спецификация ECMAScript говорила:
Механика и порядок перечисления свойств ... не указаны.
Однако в ES2015 и более поздние нецелые ключи будут возвращены в порядке вставки.
Текущий язык Spec: технически, порядок не указан.
Текущие браузеры: порядок сохраняется с большим исключением таких ключей, как «7», которые анализируются как целые числа и обрабатываются по-разному с помощью Chrome / V8.
Спецификация будущего языка (> ES2015): Как правило, вы можете ожидать, что упорядоченные сегодня вещи не будут неупорядочены. Новые API гарантируют заказ; существующие API трудно изменить. См. Ответ JMM для более подробной информации.
Лучшая ссылка ниже приведена в комментарии Tim Down:
http://code.google.com/p/v8/issues/ detail? id = 164
Эта ошибка подробно описывает проектные решения, связанные с реализацией ключевых заказов Chrome. Один вывод - это то, что для строковых ключей, которые не анализируют целое число (то есть «a» или «b», но не «3»), клавиши печатаются в порядке ввода во всех основных браузерах, и хотя это поведение не является «стандартизировано», оно IS считается существенной проблемой обратной совместимости поставщиками браузеров. Используйте на свой страх и риск.
По одному из (довольно упрямых) комментариев:
Стандарты всегда следуют за реализациями, вот откуда появился XHR, и Google делает то же самое путем внедрения Gears и последующего использования эквивалентной функциональности HTML5. Правильное решение состоит в том, чтобы ECMA формально включала де-факто стандартное поведение в следующий оборот спецификации.
Если вы полагаетесь на порядок вставки, вы находитесь за пределами спецификации ECMAScript, но внутри де-факто стандарт общего поведения браузера , если ваши ключи не анализируются как целые числа .
Весь этот ответ находится в контексте соответствия спецификации, а не того, что движок делает в определенный момент или исторически.
. Фактический вопрос очень расплывчатый.
будут ли свойства в том же порядке, что я добавил их
В каком контексте?
Ответ: это зависит от ряда факторов. В общем, no .
Иногда да
Здесь вы можете рассчитывать на порядок ключей свойств для plain
Objects
:
- Соответствующий ES2015 двигатель
- Собственные свойства
Object.getOwnPropertyNames()
,Reflect.ownKeys()
,Object.getOwnPropertySymbols(O)
Во всех случаях эти методы включают неперечислимые ключи свойств и ключи заказа, указанные в
[[OwnPropertyKeys]]
(см. ниже). Они различаются по типу ключевых значений, которые они включают (String
и / илиSymbol
). В этом контекстеString
включает целые значения.
Object.getOwnPropertyNames(O)
Возвращает собственные свойства
String
O
] ).
Reflect.ownKeys(O)
Возвращает
O
собственныеString
- иSymbol
клавиши свойства.
Object.getOwnPropertySymbols(O)
Возвращает собственные свойства
Symbol
O
.
[[OwnPropertyKeys]]
Порядок по существу: целочисленный
Strings
в порядке возрастания, нецелоподобныйStrings
в порядке создания, Символы в порядке создания. В зависимости от того, какая функция вызывает это, некоторые из этих типов могут не включаться.Специфическим языком является то, что ключи возвращаются в следующем порядке:
- .. каждый собственный ключ свойства
P
O
[объект, который повторяется], который является целым индексом, в порядке возрастания числового индекса- ... каждый собственный ключ свойства
P
изO
который является строкой, но не является целым индексом, в порядке создания свойства- ... каждый собственный ключ свойства
P
изO
, который является символом, в порядке создания свойства
Map
Если вас интересуют упорядоченные карты, вы должны рассмотреть возможность использования типа
Map
, введенного в ES2015, вместо обычногоObjects
.
Как утверждали другие, у вас нет гарантии относительно порядка, когда вы перебираете свойства объекта. Если вам нужен упорядоченный список нескольких полей, я предложил создать массив объектов.
var myarr = [{somfield1: 'x', somefield2: 'y'},
{somfield1: 'a', somefield2: 'b'},
{somfield1: 'i', somefield2: 'j'}];
Таким образом вы можете использовать регулярный цикл и иметь порядок вставки. Затем вы можете использовать метод сортировки массива, чтобы отсортировать его в новом массиве, если это необходимо.
Порядок свойств в нормальных объектах является сложным объектом в Javascript.
Хотя в ES5 явно не указан порядок, ES2015 имеет порядок в определенных случаях. Это следующий объект:
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",
Symbol(): "sym"
}
Таким образом, существует три сегмента, которые могут изменить порядок вставки (как это произошло в пример). И целые ключи не придерживаются порядка вставки.
Вопрос в том, какие методы этот порядок гарантирован в спецификации ES2015?
Следующие методы гарантируют показанный порядок:
Следующие методы / петли не гарантируют никакого порядка:
Вывод: даже в ES2015 вы не должны полагаться на порядок свойств нормального объектов в Javascript. Он подвержен ошибкам. Вместо этого используйте Map
.
Symbol
!
– Gordon
19 July 2016 в 19:41
Из стандарта JSON :
Объект представляет собой неупорядоченный набор из нулей или более пар пар имя / значение, где имя является строкой, а значение равно строка, число, логическое значение, нуль, объект или массив.
(выделение мое).
Итак, нет, вы не можете гарантировать заказ.
В современных браузерах вы можете использовать структуру данных Map
вместо объекта.
Объект Map может выполнять итерацию своих элементов в порядке размещения ...
[["key1", "value1"], ["key2", "value2"]]
или[{"key1": "value1"}, {"key2": "value2"}]
. Оберните это в своем классе, и проблема решена!var o = new OrderedObject([{key1: "blah"}]); o.key1 = "I am a value set with a setter"
– trusktr 20 February 2015 в 01:36a[3] = "val"
, вы вставляете в массив, и это, очевидно, упорядочено (по индексу 3). Когда вы выполняетеa['key1'] = "val"
или (эквивалент)a.key1 = "val"
, вы добавляете к объекту новое свойство, которое не гарантируется. Подумайте об этом как о массиве «элементы». и Object & quot; свойства ". Объект массива имеет оба, но они не являются одной и той же коллекцией. – tothemario 27 September 2016 в 17:11