const content = document.body.querySelector('.editer');
const htmlTags = content.getElementsByTagName("*");
const navs = []; // здесь let не нужен
for(let i = 0; i < htmlTags.length; i++) {
const htmlTag = htmlTags[i];
const lastNav = navs[navs.length - 1]; // resH2 всегда будет таким (см. комменты ниже)
const lastChildOfLastNav = lastNav && lastNav.children[lastNav.children.length - 1]; // resH3 всегда будет таким
switch(htmlTag.localName) {
case 'h2':
setID(htmlTag, i);
addItem(navs, htmlTag);
break;
case 'h3':
setID(htmlTag, i);
// тот find что у Вас всегда найдет последний элемент если он есть, не зачем гонять лишний цикл
if(lastNav) {
addItem(lastNav.children, htmlTag);
}
break;
case 'h4':
setID(htmlTag, i);
// опять же был лишний цикл ради последнего элемента, да еще и в него вложен такой же
if(lastChildOfLastNav) {
addItem(lastChildOfLastNav.children, htmlTag);
} else if(lastNav) {
addItem(lastNav.children, htmlTag);
}
break;
}
}
function addItem(obj, {innerText: name, id}) {
obj.push({
name,
id,
children: []
});
}
function setID(htmlTag, i) {
htmlTag.setAttribute('id', `nav-${i}`);
}