Это был старый вопрос , и мне известны обычные причины не использовать for..in
или, возможно, даже объекты, когда требуется какой-либо порядок, но я недавно натолкнулся на эту статью из MDC в операторе удаления.
Кросс-браузерные проблемы
Хотя ECMAScript делает порядок итераций объектов зависимым от реализации, может показаться, что все основные браузеры поддерживаютпорядок итераций, основанный на самом раннем добавленном свойстве, которое идет первым (по крайней мере, для свойств, не относящихся к прототипу).Тем не менее, в случае Internet Explorer, когда кто-то использует delete для свойства, возникает некоторое запутанное поведение, не позволяющее другим браузерам использовать простые объекты, такие как литералы объектов, в качестве упорядоченных ассоциативных массивов.В Проводнике, хотя значение свойства действительно установлено как неопределенное, если позднее оно добавит свойство с тем же именем, свойство будет повторяться в его старой позиции, а не в конце последовательности итерации, как можно было ожидать после того, какудалил свойство, а затем добавил его обратно.
Поэтому, если вы хотите смоделировать упорядоченный ассоциативный массив в кросс-браузерной среде, вы вынуждены либо использовать два отдельных массива (один для ключей, а другой длязначения), или создать массив объектов с одним свойством и т. д.
Похоже, что большинство основных браузеров - Chrome, Safari, Firefox и Opera перечисляют свойства объекта в порядке вставки.Это быстрый тест , чтобы подтвердить это.Это может не работать в IE, но у меня нет доступа к IE, чтобы проверить это, к сожалению.Так же IE сохраняет порядок (6/7 и далее) при переборе свойств, используя for..in
, предполагая, что мы ничего не удаляем из объекта?
Также for..in
никогда рекомендуется для итерации массивов по тем же причинам, а также тот факт, что Array.prototype
чаще подделывают, чем Object.prototype
.Однако, если свойства фактически были перечислены в порядке вставки, то, я полагаю, for..in
можно использовать и для циклического перебора массивов, при этом будет указано следующее свойство: свойства, перечисленные в Array.prototype
, будут также перечислены.
Для этого есть два решения:
Проверьте, принадлежит ли свойство объекту, используя hasOwnProperty
for(var index in object) {
if(object.hasOwnProperty(index)) {
..
}
}
Используйте новый синтаксис ES5 для определения свойств объектов и сделайте их не перечисляемыми.Это предполагает, что у вас есть полный контроль над расширением базовых прототипов, и никакой сторонний код не добавляет ничего непосредственно к прототипу.
Object.defineProperty(Array.prototype, "size", {
enumerable: false,
configurable: false,
get: function() { return this.length; },
set: undefined
});
Если все вышеперечисленные условия выполнены, и если я не пропускаю что-то важноеfor..in
можно безопасно использовать и для итерации массива:
var values = [1, 2, 3];
for(var i in values) {
values[i];
}
Так что я думаю, что это вернулось к первоначальному вопросу.Независимо от того, что спецификация говорит, IE поддерживает итерацию объекта в порядке вставки, для любых версий?Существуют ли другие браузеры, которые также не поддерживают это.