вернуть массив пар ключ-значение объекта js [duplicate]

Симон Моурир дал этот пример :

object o = null;
DateTime d = (DateTime)o;  // NullReferenceException

, где unboxing преобразование (литье) из object (или из одного из классов System.ValueType или System.Enum или из типа интерфейса) - тип значения (кроме Nullable<>) сам по себе дает NullReferenceException.

В другом направлении конверсия бокса из a Nullable<>, которая имеет HasValue, равную false , на ссылочный тип, может дать ссылку null, которая затем может привести к NullReferenceException. Классический пример:

DateTime? d = null;
var s = d.ToString();  // OK, no exception (no boxing), returns ""
var t = d.GetType();   // Bang! d is boxed, NullReferenceException

Иногда бокс происходит по-другому. Например, с помощью этого не общего метода расширения:

public static void MyExtension(this object x)
{
  x.ToString();
}

следующий код будет проблематичным:

DateTime? d = null;
d.MyExtension();  // Leads to boxing, NullReferenceException occurs inside the body of the called method, not here.

Эти случаи возникают из-за специальных правил, используемых во время выполнения при боксе Nullable<> экземпляров.

437
задан mellowsoon 2 April 2011 в 21:54
поделиться

8 ответов

Нет, порядок свойств объектов не гарантируется в JavaScript; вам нужно использовать Array.

Определение объекта из ECMAScript Third Edition (pdf) :

4.3.3 Объект

Объект является членом типа Object. Это неупорядоченный набор свойств, каждый из которых содержит примитивное значение, объект или функцию. Функция, хранящаяся в свойстве объекта, называется методом.

Поскольку ECMAScript 2015, использование объекта Map может быть альтернативой. A Map разделяет некоторые сходства с Object и гарантирует порядок ключей :

Карта выполняет итерацию своих элементов в порядке размещения, тогда как порядок итерации не указан для объектов.

349
ответ дан trincot 24 August 2018 в 06:04
поделиться

Текущий язык 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, но внутри де-факто стандарт общего поведения браузера , если ваши ключи не анализируются как целые числа .

111
ответ дан Bhuwan 24 August 2018 в 06:04
поделиться

Во время записи большинство браузеров возвращали свойства в том же порядке, в каком они были вставлены, но это явно не гарантированное поведение, поэтому на него не следует полагаться.

Спецификация ECMAScript говорила:

Механика и порядок перечисления свойств ... не указаны.

Однако в ES2015 и более поздние нецелые ключи будут возвращены в порядке вставки.

63
ответ дан Alnitak 24 August 2018 в 06:04
поделиться

Весь этот ответ находится в контексте соответствия спецификации, а не того, что движок делает в определенный момент или исторически.

Как правило, нет

. Фактический вопрос очень расплывчатый.

будут ли свойства в том же порядке, что я добавил их

В каком контексте?

Ответ: это зависит от ряда факторов. В общем, 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 в порядке создания, Символы в порядке создания. В зависимости от того, какая функция вызывает это, некоторые из этих типов могут не включаться.

Специфическим языком является то, что ключи возвращаются в следующем порядке:

  1. .. каждый собственный ключ свойства P O [объект, который повторяется], который является целым индексом, в порядке возрастания числового индекса
  2. ... каждый собственный ключ свойства P из O который является строкой, но не является целым индексом, в порядке создания свойства
  3. ... каждый собственный ключ свойства P из O, который является символом, в порядке создания свойства

Map

Если вас интересуют упорядоченные карты, вы должны рассмотреть возможность использования типа Map, введенного в ES2015, вместо простого Objects.

36
ответ дан cxw 24 August 2018 в 06:04
поделиться

Как утверждали другие, у вас нет гарантии относительно порядка, когда вы перебираете свойства объекта. Если вам нужен упорядоченный список нескольких полей, я предложил создать массив объектов.

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

Таким образом вы можете использовать регулярный цикл и иметь порядок вставки. Затем вы можете использовать метод сортировки массива, чтобы отсортировать его в новом массиве, если это необходимо.

4
ответ дан Drew Durham 24 August 2018 в 06:04
поделиться

Порядок свойств в нормальных объектах является сложным объектом в 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"
}
  1. целые ключи в порядке возрастания
  2. нормальные клавиши в порядке ввода
  3. Символы в порядке вставки

Таким образом, существует три сегмента, которые могут изменить порядок вставки (как это произошло в пример). И целые ключи не придерживаются порядка вставки.

Вопрос в том, какие методы этот порядок гарантирован в спецификации ES2015?

Следующие методы гарантируют показанный порядок:

  • Object.assign
  • Object.defineProperties
  • Object.getOwnPropertyNames
  • Object.getOwnPropertySymbols
  • ]
  • Reflect.ownKeys

Следующие методы / петли не гарантируют никакого порядка:

  • Object.keys
  • для ..in
  • JSON.parse
  • JSON.stringify

Вывод: даже в ES2015 вы не должны полагаться на порядок свойств нормального объектов в Javascript. Он подвержен ошибкам. Вместо этого используйте Map.

47
ответ дан ftor 24 August 2018 в 06:04
поделиться

Из стандарта JSON :

Объект представляет собой неупорядоченный набор из нулей или более пар пар имя / значение, где имя является строкой, а значение равно строка, число, логическое значение, нуль, объект или массив.

(выделение мое).

Итак, нет, вы не можете гарантировать заказ.

-4
ответ дан Kevin Lacquement 24 August 2018 в 06:04
поделиться

В современных браузерах вы можете использовать структуру данных Map вместо объекта.

Разработчик mozilla> Map

Объект Map может выполнять итерацию своих элементов в порядке размещения ...

8
ответ дан Michel 24 August 2018 в 06:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: