#javascript #arrays #function #methods #javascript-objects
Вопрос:
Исходный контент можно найти здесь: https://github.com/LinkedInLearning/javascript-essential-training-2832077/tree/main/08_17. Код, о котором идет речь, находится в этом блоке прямо здесь:
import backpackObjectArray from "./components/data.js";
const content = backpackObjectArray.map((backpack)=>{
let backpackArticle = document.createElement("article");
backpackArticle.classList.add("backpack");
// Set article ID to the backpack.id property
backpackArticle.setAttribute("id", backpack.id);
backpackArticle.innerHTML=`
<figure class="backpack__image">
<img src=${backpack.image} alt="" />
</figure>
<h1 class="backpack__name">${backpack.name}</h1>
<ul class="backpack__features">
<li class="packprop backpack__volume">Volume:<span> ${
backpack.volume
}l</span></li>
<li class="packprop backpack__color">Color:<span> ${
backpack.color
}</span></li>
<li class="backpack__age">Age:<span> ${backpack.backpackAge()} days old</span></li>
<li class="packprop backpack__pockets">Number of pockets:<span> ${
backpack.pocketNum
}</span></li>
<li class="packprop backpack__strap">Left strap length:<span> ${
backpack.strapLength.left
} inches</span></li>
<li class="packprop backpack__strap">Right strap length:<span> ${
backpack.strapLength.right
} inches</span></li>
<li class="feature backpack__lid">Lid status:<span> ${
backpack.lidOpen ? "open" : "closed"
}</span></li>
</ul>
`;
return backpackArticle;
})
const main = document.querySelector(".maincontent");
content.forEach((backpack)=>{
main.append(backpack);
}
)
В сущности, можно ли просто использовать цикл forEach для вывода того же результата, что и при использовании метода массива map (), который заключается в выводе HTML-статьи для каждого объекта?
Комментарии:
1. Да, это возможно, но громоздко, почему бы вам не предпочесть
forEach
map
?
Ответ №1:
Вы определенно можете использовать цикл forEach, если захотите, просто код будет немного другим. Использование карты не обязательно, если вам нравится, как выглядит новый код.
import backpackObjectArray from "./components/data.js";
const main = document.querySelector(".maincontent");
backpackObjectArray.forEach((backpack) => {
let backpackArticle = document.createElement("article");
backpackArticle.classList.add("backpack");
// Set article ID to the backpack.id property
backpackArticle.setAttribute("id", backpack.id);
backpackArticle.innerHTML = `
<figure class="backpack__image">
<img src=${backpack.image} alt="" />
</figure>
<h1 class="backpack__name">${backpack.name}</h1>
<ul class="backpack__features">
<li class="packprop backpack__volume">Volume:<span> ${
backpack.volume
}l</span></li>
<li class="packprop backpack__color">Color:<span> ${
backpack.color
}</span></li>
<li class="backpack__age">Age:<span> ${backpack.backpackAge()} days old</span></li>
<li class="packprop backpack__pockets">Number of pockets:<span> ${
backpack.pocketNum
}</span></li>
<li class="packprop backpack__strap">Left strap length:<span> ${
backpack.strapLength.left
} inches</span></li>
<li class="packprop backpack__strap">Right strap length:<span> ${
backpack.strapLength.right
} inches</span></li>
<li class="feature backpack__lid">Lid status:<span> ${
backpack.lidOpen ? "open" : "closed"
}</span></li>
</ul>
`;
main.append(backpackArticle);
});
Комментарии:
1. Спасибо вам за пример! Однако теперь мне любопытно, почему большинство людей говорят, что простое использование forEach приводит к большему количеству кода, когда мне кажется, что это не так
2. Не знаю, почему они так говорят, лол. Очевидно, что это не так.
Ответ №2:
*Pseudo-code* Array.prototype.map(function(ea){return backpackArticle})
просто создаст новый массив и будет включать все, что вы возвращаете в каждой итерации.
Вы можете достичь того же самого другими способами, но, как уже было сказано, с помощью большего количества кода. На самом деле «значимость» в данном случае заключается в том, чтобы просто достичь желаемого результата с меньшим количеством кода.
Я думаю, что в вашем примере это означает явное создание нового массива, а затем явное добавление каждого backpackArticle
из них к <main>
использованию forEach. Вы можете пропустить создание нового массива с помощью карты.
Ответ №3:
Редактировать
Извините, я, кажется, недостаточно внимательно прочитал ваш вопрос. В вашем случае, да, вы можете обмениваться .map
.forEach
созданными элементами и добавлять их напрямую, не сохраняя их в промежуточном массиве.
Впрочем, остальное я оставлю как есть, может быть, кому-то это покажется полезным.
В качестве несколько общего ответа: «Да, вы могли бы использовать .forEach
и получить те же результаты». И вы также можете сделать это с .reduce
помощью . Однако, если вы хотите получить список результатов из списка источников (как в вашем примере), .map
это правильный путь.
Я собираюсь ответить на ваш вопрос в более общем плане, потому что мне кажется, что вы спрашиваете о разнице между
.forEach
и.map
в целом.
Каждый метод Array.prototype
существует с определенной целью. Цель .map
состоит в том, чтобы спроецировать (или «сопоставить», отсюда и название) функцию на все элементы списка. Поэтому, если вы хотите перейти от списка значений к списку других значений, вы можете использовать .map
.
const sources = [1, 2, 3, 4, 5];
const results = sources.map(n => n 1);
console.log(results); // logs [2, 3, 4, 5, 6]
Чтобы получить то же .forEach
самое , у вас будет такое же количество переменных, но вам нужно будет запрограммировать еще два шага: один для создания results
массива, другой для добавления в него элементов вручную.
const sources = [1, 2, 3, 4, 5];
const results = [];
sources.forEach(n => {
results.push(n);
});
console.log(results);
Путем прямого сравнения вы можете легко увидеть, что использование .forEach
результатов дает немного больше кода, который менее декларативен и более императивен по стилю.
Как упоминалось ранее, вы также можете использовать .reduce
для сопоставления функции со значением и накапливать его в результирующий список. На самом деле, с помощью этого можно записать огромное количество операций .reduce
. Если вам интересно, поищите transducers
, есть несколько доступных библиотек на разных языках.
Но вернемся к примеру с использованием reduce
:
const sources = [1, 2, 3, 4, 5];
const results = sources.reduce((acc, n) => acc.concat(n 1), []);
console.log(results); // logs [2, 3, 4, 5, 6]