Почему цикл for for-each не выполняет итерацию по моему объекту ассоциативного массива JavaScript?
// defining an array
var array = [];
// assigning values to corresponding keys
array["Main"] = "Main page";
array["Guide"] = "Guide page";
array["Articles"] = "Articles page";
array["Forum"] = "Forum board";
// expected: loop over every item,
// yet it logs only "last" assigned value - "Forum"
for (var i = 0; i < array.length; i++) {
console.log(array[i]);
}
РЕДАКТИРОВАТЬ: JQuery each()
может быть полезным: https://api.jquery.com/jQuery.each/
javascript
arrays
foreach
Шимон Тода
источник
источник
associative arrays
JS нет таких вещей : это либо обычный массив, либо объект. Ничто не мешает добавлять нечисловые свойстваArray
, но это не делает этогоassociative
- в частности,length
свойство не будет автоматически считать эти свойства.Ответы:
.length
Свойство отслеживает только свойство с числовыми индексами (ключи). Вы используете строки для ключей.Ты можешь сделать это:
Чтобы быть в безопасности, рекомендуется в таких циклах убедиться, что ни одно из свойств не является неожиданным результатом наследования:
edit - вероятно, сейчас стоит отметить, что
Object.keys()
функция доступна в современных браузерах, в Node и т. д. Эта функция возвращает «собственные» ключи объекта в виде массива:Функция обратного вызова, передаваемая в,
.forEach()
вызывается с каждым ключом, а индекс ключа в массиве возвращаетсяObject.keys()
. Также передается массив, через который проходит функция, но этот массив нам не очень полезен; нам нужен оригинальный объект . К нему можно получить доступ напрямую по имени, но (на мой взгляд) немного приятнее передать его явно, что достигается передачей второго аргумента.forEach()
- исходному объекту - который будет связан какthis
внутри обратного вызова. (Просто увидел, что это было отмечено в комментарии ниже.)источник
var arr_jq_TabContents = {};
? Я имею в виду {}[]
и{}
? Только разные прототипы?Object.keys(arr_jq_TabContents).forEach( function(key) { ... } );
Это очень простой подход. Преимущество в том, что вы также можете получить ключи:
Для ES6:
Для ES6: (если вам нужно значение, индекс и сам массив)
источник
var
в циклах, предлагающих область видимости, которая не существует. Используйтеvar
перед петлей илиlet
в петле.for
цикле генерирует область видимости, ограниченную теломfor
цикла. Но в JavaScript объявленная переменнаяvar
всегда является функцией global, даже если вы пишете ее вfor
цикле. Смотрите здесь: davidwalsh.name/for-and-against-letvar
в Javascript создает переменные в памяти даже после завершения цикла.Уже есть несколько простых примеров, но я заметил из того, как вы сформулировали свой вопрос, что вы, вероятно, пришли из фона PHP, и вы ожидаете, что JavaScript будет работать таким же образом - это не так. PHP
array
сильно отличается от JavaScriptArray
.В PHP ассоциативный массив может делать большую часть того, что может численно индексированный массив (
array_*
функции работают, вы можетеcount()
это и т. Д.). Вы просто создаете массив и начинаете присваивать строковые индексы вместо числовых.В JavaScript все является объектом (кроме примитивов: строковых, числовых, логических), а массивы представляют собой определенную реализацию, которая позволяет иметь числовые индексы. Все , что толкнул в массив будет влияние на его
length
, и может повторяться по сравнению с использованием методов Array (map
,forEach
,reduce
,filter
,find
и т.д.) Однако, поскольку все является объектом, вы всегда свободны просто присвоить свойства, потому что это то , что вы делаете , чтобы любой объект. Обозначение в квадратных скобках - это просто еще один способ получить доступ к свойству, поэтому в вашем случае:на самом деле эквивалентно:
Из вашего описания я предполагаю, что вам нужен «ассоциативный массив», но для JavaScript это простой случай использования объекта в качестве хэш-карты. Кроме того, я знаю, что это пример, но избегайте бессмысленных имен, которые описывают только тип переменной (например
array
), и имя, основанное на том, что оно должно содержать (напримерpages
). Простые объекты не имеют много хороших прямых путей к итерация, так часто мы повернем затем в массивы первых , используяObject
методы (Object.keys
в данном случае - есть такжеentries
иvalues
добавляется в некоторых браузерах прямо сейчас) , которые мы можем цикл.источник
arr_jq_TabContents[key]
видит массив как форму с 0 индексами.источник
Вот простой способ использовать ассоциативный массив в качестве универсального типа объекта:
источник
Если node.js или браузер поддерживается
Object.entries()
, его можно использовать в качестве альтернативы использованиюObject.keys()
( https://stackoverflow.com/a/18804596/225291 ).в этом примере
forEach
используется Destructuring присваивание массива.источник
Это (по сути) неправильно в большинстве случаев:
Это создает неэлементное свойство в массиве с именем
Main
. Хотя массивы являются объектами, обычно вы не хотите создавать для них неэлементные свойства.Если вы хотите индексировать
array
по этим именам, обычно вы используетеMap
простой объект или объект, а не массив.С
Map
(ES2015 +), который я назову,map
потому что я креативен :вы затем перебирать его , используя итераторы из своих
values
,keys
, илиentries
способов, например:Используя простой объект, который я творчески назову
obj
:вы затем итерацию его содержимое с помощью
Object.keys
,Object.values
илиObject.entries
, например:источник
в этом коде я использовал метод скобок для вызова значений в массиве, потому что он содержал массив, однако вкратце идея о том, что переменная i имеет ключ свойства и с циклом, который называет оба значения ассоциированного массива
Идеальный метод, если вам интересно, нажмите как
источник
Ты можешь сделать это
источник