JS: как добавить к ключу объекта счётчик цикла?

Есть условный объект вида:

let obj = {
    smallNews: {
        title1: "Заголовок 1",
        title2: "Заголовок 2",
        title3: "Заголовок 3",
        title4: "Заголовок 4",
    }
}

Когда я обращаюсь напрямую к какому-то из ключей, то могу вывести его значение:

console.log(obj.smallNews.title2) // Заголовок 2

А как вывести все значения в обычном цикле? Т.е. как добавить в цикле к ключу title значение счётчика?

Сейчас делаю так: сначала формирую строку, а потом с помощью eval получаю значение. Но, имхо, это не самый удачный способ. Можно ли сделать иначе?

let obj = {
    smallNews: {
        title1: "Заголовок 1",
        title2: "Заголовок 2",
        title3: "Заголовок 3",
        title4: "Заголовок 4",
    }
}

for (let i = 1; i<= 4; i++) {
  let str = 'obj.smallNews.title'+i;
    console.log(eval(str));
}


Ответы (3 шт):

Автор решения: Oliver Patterson

let obj = {
    smallNews: {
        title1: "Заголовок 1",
        title2: "Заголовок 2",
        title3: "Заголовок 3",
        title4: "Заголовок 4",
    }
}

for (const key in obj.smallNews)
{
    console.log(obj.smallNews[key]);
}


Или же:

let obj = {
    smallNews: {
        title1: "Заголовок 1",
        title2: "Заголовок 2",
        title3: "Заголовок 3",
        title4: "Заголовок 4",
    }
}

Object.values(obj.smallNews).forEach((title) =>
{
  console.log(title);
});


Но у меня вопрос, почему бы не использовать изначально массив?

let obj = {
    smallNews: [
        "Заголовок 1",
        "Заголовок 2",
        "Заголовок 3",
        "Заголовок 4",
    ]
};

obj.smallNews.forEach((title) =>
{
  console.log(title);
});


После комментария:

let obj = {
    smallNews: {
        title1: "Заголовок 1",
        title2: "Заголовок 2",
        title3: "Заголовок 3",
        title4: "Заголовок 4",
    }
}

for (let i = 1; i<= 4; i++) {
    console.log(obj.smallNews['title' +i]);
}

→ Ссылка
Автор решения: Анастасия Сергеевна

Если нужно вывести в виде массива

let a = []
for ( i in obj.smallNews) {
    a.push(obj.smallNews[i])
    console.log(a);
}
→ Ссылка
Автор решения: yar85

А как вывести все значения в обычном цикле?

Если задача именно в этом, то ключи в принципе не требуются (в том смысле, что незачем их имена вычислять) - можно просто получить значения соотв. методом:

const obj = {
  smallNews: {
    title1: "Заголовок 1",
    title2: "Заголовок 2",
    title3: "Заголовок 3",
    title4: "Заголовок 4",
  },
};

for (const value of Object.values(obj.smallNews))
  console.log(value);


То есть, я конечно вижу и понимаю о чем задан вопрос - по сути, он о способе решения задачи "вычислить имена ключей объекта"... но возможно, что сама задача поставлена неправильно/неоптимально. Ведь если подумать, то вычисление ключей таким образом, создает ряд потенциальных проблем:

  • вероятность ошибиться в ожидании наличия указанных ключей (получения undefined)
  • вероятность обратиться к прототипному свойству объекта, вместо собственного
  • затрудненная отладка, как из-за первых двух пунктов, так и из-за всяких других мелочей (например, причины возможного вывода в консоли а-ля "не удалось получить свойство значения undefined" несколько малоочевидны, и надо код открывать чтобы найти место с тем самым циклом)
  • банально пустая трата ресурсов на строковые операции (это совсем не критично когда лишь 4 ключа, но в циклах по длинным массивам толстых объектов, да с вложенностью - может опечалить).

Третий пункт спорный, но остальные вполне реальны, имхо.
Само по себе, вычисление ключей это не совсем зло... точнее, это зло которое бывает необходимым. Вот есть ли в нем необходимость - именно то, о чем написан данный ответ, то о чем я призываю задумываться (т.к. сам временами напрасно усложняю решения ? ).

→ Ссылка