Как реализовать метод addClass с поддержкой цепочки вызовов
Что проверяют
Понимаете ли вы, как работает this при вызове метода и почему цепочка держится на возврате объекта. Задача выросла из jQuery, поэтому следом просят добавить removeClass и toggleClass, поддержать несколько элементов или несколько классов за раз.
Как отвечать
Суть цепочки в одном правиле: метод, который меняет состояние, возвращает this. Тогда результат $('.card').addClass('active') снова обёртка, и у неё можно вызвать следующий метод. Каркас сильного ответа:
- обёртка над коллекцией: в конструкторе
this.elements = Array.from(document.querySelectorAll(selector)), чтобы метод работал на всех совпадениях, а не на первом; - разбор аргумента: строку вида
'active visible'делите по пробелам черезclassName.split(/\s+/).filter(Boolean)и передавайте вel.classList.add(...names). Метод принимает несколько классов сразу и сам не добавляет дубли; - пустая выборка: если элементов нет, метод всё равно возвращает
this, иначе следующий вызов в цепочке упадёт сTypeError; - где хранить методы: объявляйте их в теле класса или на прототипе, тогда все экземпляры делят одну функцию.
Хорошо добавить различие между методами-модификаторами и методами-запросами. addClass, removeClass и toggleClass возвращают this, а hasClass возвращает boolean и закономерно завершает цепочку. Если спросят про старые браузеры, classList поддерживается везде уже много лет, а ручная склейка className пригодится разве что для объяснения, как это устроено внутри.
Где спотыкаются
Передают в classList.add строку с пробелом как есть. Браузер бросает DOMException с именем InvalidCharacterError, а пустая строка даёт SyntaxError, поэтому разбор аргумента обязателен.
Объявляют методы стрелочными функциями в объектном литерале. У стрелки нет своего this, она берёт его из внешней области, и return this вернёт совсем не обёртку.
Работают только с querySelector. Такая реализация молча меняет первый найденный элемент, а интервьюер почти наверняка проверит селектор, под который подходят несколько.