Сегодня мы разберем вопросы, которые часто задают на собеседовании фронтенд-разработчиков. Я выбрал темы, с которыми сталкивался лично и на которых можно «споткнуться», даже если вы в целом знакомы с предметом, но не учли подводные камни.
Вопрос 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 внутри функции отразится на исходном объекте.
Помимо теоретического понимания промисов, важно уметь решать практические задачи.
Задача: Реализуйте функцию 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.
Это стандартный вопрос, на который можно дать развернутый ответ. Если кратко, процесс включает следующие этапы:
DNS-запрос: Браузер преобразует доменное имя в IP-адрес.
TCP/IP-соединение: Устанавливается надежное соединение с сервером.
HTTP-запрос/ответ: Браузер отправляет запрос и получает HTML-код страницы.
Парсинг (Parsing): Браузер анализирует HTML и строит DOM-дерево (Document Object Model).
Формирование CSSOM: Параллельно парсится CSS и строится CSSOM-дерево (CSS Object Model).
Построение Render Tree: DOM и CSSOM объединяются в Render Tree (дерево рендеринга), которое содержит только видимые элементы.
Layout (или Reflow): Браузер вычисляет точное положение и размер каждого элемента на странице.
Paint: Браузер отрисовывает пиксели (например, цвета, тени, шрифты).
Composite: Отдельные слои страницы объединяются в окончательное изображение, которое видит пользователь.
Копирование объектов в JavaScript может быть поверхностным (Shallow Copy) или глубоким (Deep Copy).
Подходит для объектов без вложенности. Используйте оператор spread или Object.assign().
const obj = { name: "Max", age: 25 }
const copySpread = { ...obj }
const copyAssing = Object.assign({}, obj)Способ 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 - работа с областями видимости переменных
Промисы - асинхронные операции и их комбинирование
Загрузка страницы- понимание полного цикла рендеринга
Копирование объектов - разные подходы для разных ситуаций
Главный совет: На собеседовании важно не только знать правильный ответ, но и понимать почему он правильный.