Как можно сделать код чище?

Создаю с помощью JS таблицу. Присваиваю циклом повторяющиеся стили и атрибуты. Прошу, подскажите можно ли упростить мой код?

let elements = document.querySelectorAll("th");

if(elements) {
  for (let i = 0; i < elements.length; i++) {
    elements[i].classList.add("align-top");
    elements[i].setAttribute("scope", "col");
    elements[i].setAttribute("role", "button");

  }
}

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

Автор решения: EzioMercer

querySelectorAll в отличии от querySelector возврашает пустой NodeList потому можно убрать проверку if (elements) цикл и так не запустится:

let elements = document.querySelectorAll("th");

for (let i = 0; i < elements.length; i++) {
  elements[i].classList.add("align-top");
  elements[i].setAttribute("scope", "col");
  elements[i].setAttribute("role", "button");
}

Но я бы переписал ещё:

  • let на const, чтобы не было соблазна его переопределять
  • для простого перебора, обычный цикл на for of
const elements = document.querySelectorAll('th');

for (const element of elements) {
  element.classList.add('align-top');
  element.setAttribute('scope', 'col');
  element.setAttribute('role', 'button');
}
→ Ссылка
Автор решения: Михаил Ребров

Эта проверка лишняя, т.к. querySelectorAll всегда возвращает NodeList

if(elements) { 
   // ...
}

for-i можно заменить на for-of

for (let i = 0; i < elements.length; i++) {
   // ...
}

так попроще

for (const element of elements) {
   // ...
}

а лучше пойти еще дальше и вызвать на объекте NodeList метод forEach и туда передать обработчик элементов.

document.querySelectorAll('th').forEach(function(element) {
    // ...
})

Заодно получится избавиться от лишних присваиваний и проверок

let elements = // ...

С атрибутами двоякая ситуация...
Если бы их было больше то, однозначно стоило бы ввести вспомогательную функцию, которая вставляет атрибуты по json'у:

function setAttributes(el, attrs) {
  for(var key in attrs) {
    el.setAttribute(key, attrs[key]);
  }
}

и потом вызвать...
тогда получилось бы

document.querySelectorAll('th').forEach(function(element) {
    setAttributes(element, {
        class: "align-top", 
        scope: "col", 
        role: "button"});
})

но c объявлением функции то, то на то и выходит... было бы больше атрибутов или нужно было бы это чаще делать - стоило бы попробовать

Замечание:
Как и следует из названия, функция setAttributes устанавливает атрибуты, а не модифицирует их. Соответственно, нужно быть аккуратнее с использованием данной функции вместе с атрибутом class. Если требуется не установить значение атрибута class, а модифицировать его, добавив новое значение список, классов или наоборот удяляя что-то из этого списка, при этом сохранив часть прошлого списка классов, то лучше это делать не с помощью setAttributes, а стандартными средствами classList.add().

ну а так, пока что самый короткий и прочтой вариант выглядит так (без setAttributes)

document.querySelectorAll('th').forEach(function(element) {
    element.classList.add("align-top");
    element.setAttribute("scope", "col");
    element.setAttribute("role", "button");
})
→ Ссылка