#javascript #arrays #dom #foreach
#javascript #массивы #dom #foreach
Вопрос:
У меня есть метод forEach, который возвращает console.log() для каждого элемента в массиве. Если я помещаю в него шаблонные литералы, я печатаю в консоли: [object HTMLLIElement] вместо правильной оценки объекта "<li class="sel">..."
const container = document.querySelector("#start");
let sel = container.querySelectorAll(".sel");
//The following works as it should:
// sel.forEach((element, pos) => console.log( element,pos));
//This , however does not
sel.forEach((element, pos) => console.log( ` ${element} ${pos} `)); //and prints " [object HTMLLIElement] 0 "
<div id="start">
<ul>
<li class="sel">valoare 1</li>
<li class="sel">valoare 2</li>
<li class="sel">valoare 3</li>
<li>valoare 4</li>
<li class="sel">valoare 5</li>
</ul>
</div>
Комментарии:
1.
console.log
(в браузере), специально обрабатывает HTMLЭлементы и предоставляет им интерактивное меню. Преобразуя их в строку с шаблонным литералом, вы теряете эту возможность. Если вы также хотите зарегистрировать позицию, вы можете попробоватьconsole.log(element, " ", pos)
.2. «вместо правильной оценки объекта» что это значит? Вы выполняете toString() для объекта.
3. У меня возникли проблемы с пересмотром редактирования вопроса, потому что кто-то другой также исправил его, когда я пытался отправить изменения — где я сказал правильную оценку, которая появляется в консоли «<li class=»sel»> …» (когда я запускаю код, который работает sel.forEach((элемент, pos) => console.log(элемент, pos));
4. Я не думаю, что мои ответы или ответы @iota являются элитарными. Я думаю, что я собрал довольно исчерпывающий ответ со ссылками на соответствующие ресурсы, чтобы вы могли полностью понять, что происходит и как получить то, что вы хотите.
5. (что меня беспокоило, так это то, что я не закончил изменять вопрос, заметив некоторые ошибки в том, как он был сформулирован, и сразу же последовал отказ … прежде чем мне удалось даже отправить изменения)
Ответ №1:
Вы можете интерполировать элементы outerHTML
.
const container = document.querySelector("#start");
let sel = container.querySelectorAll(".sel");
sel.forEach((element, pos) => console.log( `${element.outerHTML} ${pos} `));
<div id="start">
<ul>
<li class="sel">valoare 1</li>
<li class="sel">valoare 2</li>
<li class="sel">valoare 3</li>
<li>valoare 4</li>
<li class="sel">valoare 5</li>
</ul>
</div>
Ответ №2:
Использование шаблонных литералов вызывает принудительный .toString()
вызов element
ссылки, которая возвращается как [object HTMLLIElement]
.
Из документов:
Если этот метод не переопределен в пользовательском объекте, toString() возвращает «[тип объекта]«, где type — это тип объекта.
Без шаблонного литерала вы предоставляете браузеру возможность отображать значение, которое возвращает неявный результат вызова element.valueOf()
и возвращает нераспределенный HTML-код элемента.
const div = document.querySelector("div");
console.log(div); // Implicit .valueOf() call
console.log(div.valueOf()); // Explicit .valueOf() call
const el = div;
console.log(`${div}`); // Implicit .toString() call
console.log(div.toString()); // Explicit .toString() call
<div>test</div>
Итак, при использовании шаблонных литералов вам нужно понимать, что вы просите зарегистрировать строковое представление самого элемента, а не какое-либо свойство элемента.
В вашем случае шаблонные литералы не нужны, потому forEach
что аргументы предоставляют вам доступ к данным, которые могут вам понадобиться, через интерфейс узла элемента, а вызов element.outerHTML
вернет HTML всего элемента.
document.querySelectorAll("#start .sel").forEach(
(element, pos) => {
// The forEach element argument provides a reference to the
// element instance being iterated. You can access anything
// you need to using that element's API:
console.log(element.nodeName,
element.className,
element.textContent,
element.outerHTML,
pos);
}
);
<div id="start">
<ul>
<li class="sel">valoare 1</li>
<li class="sel">valoare 2</li>
<li class="sel">valoare 3</li>
<li>valoare 4</li>
<li class="sel">valoare 5</li>
</ul>
</div>