Вопрос №1: Очередь событий и вывод консоли
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');
Ответ: 1, 4, 3, 2.
Почему опытные разработчики ошибаются:
Многие знают, что setTimeout() асинхронен, но забывают о том, что микрозадачи (Promise) выполняются до макрозадач (setTimeout()).
Интервьюеры любят визуализацию процесса выполнения задач, поэтому полезно нарисовать схему очередей вызовов и их обработки.
Вопрос №2: Специфичность стилей CSS
Какой стиль победит?
#header .nav li a { color: blue; }
.nav-link.active { color: red; }
Ответ: синий цвет (blue).
Ошибка многих разработчиков заключается в предположении, что большее количество классов повышает специфичность стиля. На самом деле один идентификатор всегда побеждает любое число классов.
Специфичность считается как кортеж чисел, а не одно целое значение.
Вопрос №3: Утечка памяти через замыкания
Что выведет следующий код?
function createButtons() {
const buttons = [];
for (var i = 0; i < 5; i++) {
buttons.push(() => console.log(i));
}
return buttons;
}
createButtons().forEach(btn => btn());
Ответ: пять раз подряд выводит цифру 5.
Исправление ошибки можно сделать двумя способами:
- Использовать ключевое слово
letвместоvar, - Создать немедленно вызываемую функцию (
IIFE), которая захватывает текущее значение переменной.
Этот вопрос проверяет понимание разницы между областями видимости и блоковым контекстом исполнения кода.
Вопрос №4: Контекст вызова функции this
Какая разница между использованием стрелочных функций и обычных функций при обращении к объекту?
const obj = {
name: 'Widget',
getName: () => this.name,
getNameFn: function() { return this.name; }
};
Стрелочные функции наследуют контекст от родительской области видимости, тогда как обычные функции имеют собственный контекст вызова.