> Как реализовать метод addClass с поддержкой цепочки вызовов (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Сбер

Стек: JavaScript

> Пример ответа

Короткий ответ

Метод addClass с поддержкой цепочки вызовов реализуется через возврат this из метода. Это позволяет последовательно вызывать методы на одном и том же объекте. В контексте DOM-элементов нужно использовать classList.add(), но при этом возвращать сам элемент, а не classList. Для совместимости со старыми браузерами можно работать со строкой className.

Подробное объяснение

Цепочка вызовов (method chaining) - это паттерн, при котором каждый метод возвращает объект, на котором он вызван. Это возможно благодаря тому, что this внутри метода ссылается на текущий объект.

Для DOM-элементов есть два подхода:

  1. Современный: использовать classList.add() - он возвращает undefined, поэтому нужно явно вернуть this.
  2. Классический: работать со строкой className, добавляя классы через пробел.

Важно учитывать, что classList не поддерживается в IE9 и ниже, поэтому для legacy-кода используется строковый подход.

При реализации нужно решить: расширяем ли мы нативный Element.prototype (что рискованно) или создаём обёртку. Для библиотек лучше второй вариант, для учебных задач - первый.

На практике

Типичная реализация для DOM-элемента:

JAVASCRIPT
// Расширение прототипа (для учебных целей)
Element.prototype.addClass = function(className) {
this.classList.add(className);
return this;
};
// Использование
document.querySelector('.box')
.addClass('active')
.addClass('visible');

Для обёртки:

JAVASCRIPT
class DOMHelper {
constructor(element) {
this.element = element;
}
addClass(className) {
this.element.classList.add(className);
return this;
}
removeClass(className) {
this.element.classList.remove(className);
return this;
}
}
const helper = new DOMHelper(document.querySelector('.box'));
helper.addClass('active').addClass('visible');

Для legacy-поддержки:

JAVASCRIPT
Element.prototype.addClass = function(className) {
const classes = this.className.split(' ').filter(Boolean);
if (!classes.includes(className)) {
classes.push(className);
this.className = classes.join(' ');
}
return this;
};

Как отвечать на собеседовании

Начни с ключевого принципа: возврат this из метода. Затем покажи два варианта: через classList и через строку className. Обязательно упомяни, почему нельзя просто вернуть результат classList.add() - он возвращает undefined. Если спросят про расширение прототипа, скажи о рисках: конфликты имён, влияние на все элементы, проблемы с будущими стандартами. Предложи альтернативу - обёртку или функцию-хелпер.

Что проверяет интервьюер

  • Понимание контекста this и механизма цепочек вызовов.
  • Знание DOM API: classList vs className.
  • Осознание последствий модификации нативных прототипов.
  • Умение писать совместимый код (legacy-поддержка).
  • Способность предложить несколько решений с trade-off.

Типичные ошибки

  • Возврат this.classList вместо this - ломает цепочку.
  • Забывают проверять дубликаты классов при работе со строкой className.
  • Расширяют Element.prototype без оговорки о рисках.
  • Не учитывают, что classList.add() игнорирует дубликаты, а строковый подход - нет.
  • Путают className (строка) и classList (DOMTokenList).

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью