Частые вопросы на собеседовании Frontend-разработчика

Частые вопросы на собеседовании Frontend-разработчика

1st December 2025

Сегодня мы разберем вопросы, которые часто задают на собеседовании фронтенд-разработчиков. Я выбрал темы, с которыми сталкивался лично и на которых можно «споткнуться», даже если вы в целом знакомы с предметом, но не учли подводные камни.

1. Затенение переменных (Shadowing)

Вопрос 1: Что выведет этот код?

var a = 2
function foo(a = 4) {
  a = 1
  console.log(a)
}
foo(3)
console.log(a)

Ответ:

1
2

Объяснение: Параметр функции a «затеняет» (shadows) внешнюю переменную a. Внутри функции мы работаем с локальной переменной a, поэтому ее изменение не влияет на внешнюю переменную. Обратите внимание: даже если вызвать foo() без аргумента, сработает значение по умолчанию, и в первом console.log мы все равно увидим 1.


Вопрос 2: Какой будет результат у этого скрипта?

var obj = { x: 1 }
function fooObj(obj) {
  obj.x = 2
  console.log(obj)
}
fooObj(obj)
console.log(obj)

Ответ:

{ x: 2 }
{ x: 2 }

Объяснение: В отличие от примитивов, объекты передаются по ссылке. Параметр obj внутри функции - это ссылка на тот же объект, что и внешняя переменная obj. Поэтому изменение свойства x внутри функции отразится на исходном объекте.

2. Промисы (Promises)

Помимо теоретического понимания промисов, важно уметь решать практические задачи.

Задача: Реализуйте функцию sum, которая принимает произвольное количество промисов с числами и возвращает промис с суммой этих чисел.

const p1 = new Promise(resolve => resolve(1));
const p2 = new Promise(resolve => resolve(2));
const p3 = new Promise(resolve => resolve(3));

sum().then(console.log);            // 0
sum(p1).then(console.log);          // 1
sum(p1, p2).then(console.log);      // 3
sum(p1, p2, p3).then(console.log);  // 6

Решение:

function sum(...promises) {
  return Promise.all(promises)
    .then(numbers => numbers.reduce((acc, num) => acc + num, 0))
    .catch(error => console.error(error))
}

Объяснение:

  • С помощью оператора rest (...) мы собираем все переданные аргументы в массив промисов.

  • Promise.all ожидает выполнения всех промисов и возвращает массив с результатами.

  • Метод reduce суммирует все элементы массива, начиная с 0 (что корректно обрабатывает случай вызова sum() без аргументов).

Совет: Для уверенного решения таких задач необходимо знать все статические методы промисов: Promise.resolve, Promise.reject, Promise.all, Promise.allSettled, Promise.any, Promise.race.


3. Что происходит, когда мы открываем сайт в браузере?

Это стандартный вопрос, на который можно дать развернутый ответ. Если кратко, процесс включает следующие этапы:

  1. DNS-запрос: Браузер преобразует доменное имя в IP-адрес.

  2. TCP/IP-соединение: Устанавливается надежное соединение с сервером.

  3. HTTP-запрос/ответ: Браузер отправляет запрос и получает HTML-код страницы.

  4. Парсинг (Parsing): Браузер анализирует HTML и строит DOM-дерево (Document Object Model).

  5. Формирование CSSOM: Параллельно парсится CSS и строится CSSOM-дерево (CSS Object Model).

  6. Построение Render Tree: DOM и CSSOM объединяются в Render Tree (дерево рендеринга), которое содержит только видимые элементы.

  7. Layout (или Reflow): Браузер вычисляет точное положение и размер каждого элемента на странице.

  8. Paint: Браузер отрисовывает пиксели (например, цвета, тени, шрифты).

  9. Composite: Отдельные слои страницы объединяются в окончательное изображение, которое видит пользователь.


Как скопировать объект в JavaScript?

Копирование объектов в JavaScript может быть поверхностным (Shallow Copy) или глубоким (Deep Copy).

Поверхностное копирование (Shallow Copy)

Подходит для объектов без вложенности. Используйте оператор spread или Object.assign().

const obj = { name: "Max", age: 25 }
const copySpread = { ...obj }
const copyAssing = Object.assign({}, obj)
Глубокое копирование (Deep Copy)

Способ 1: JSON.parse(JSON.stringify(obj))

const obj = { user: { name: "Max" } }
const deepCopy = JSON.parse(JSON.stringify(obj))

Недостаток: Этот метод не копирует специальные типы, такие как Date, Symbol, undefined или Map/Set, и обрывает циклические ссылки.

Способ 2: structuredClone() (современный и надежный)

const obj =  {
    name: "Tom",
    birthDate: new Date('1994-06-08')
};
const deepCopy = structuredClone(obj);
console.log(deepCopy.birthDate.getFullYear()) // 1994

Итоги

Мы разобрали несколько ключевых тем, которые регулярно встречаются на собеседованиях:

Shadowing - работа с областями видимости переменных

Промисы - асинхронные операции и их комбинирование

Загрузка страницы- понимание полного цикла рендеринга

Копирование объектов - разные подходы для разных ситуаций

Главный совет: На собеседовании важно не только знать правильный ответ, но и понимать почему он правильный.

Последние посты
Частые вопросы на собеседовании Frontend-разработчика
Знакомство с Mobx
Пайпы в Angular