0 added
0 removed
Original
2026-01-01
Modified
2026-02-26
1
<p>В подборку попали типичные вопросы об отладке, с которыми сталкиваются на собеседованиях разработчики на JavaScript. Попытайтесь ответить на них самостоятельно, а потом сравните ответ с правильным решением.</p>
1
<p>В подборку попали типичные вопросы об отладке, с которыми сталкиваются на собеседованиях разработчики на JavaScript. Попытайтесь ответить на них самостоятельно, а потом сравните ответ с правильным решением.</p>
2
<h2>Содержание</h2>
2
<h2>Содержание</h2>
3
<ul><li><a>Вопрос 1: объекты и ссылки на объекты</a></li>
3
<ul><li><a>Вопрос 1: объекты и ссылки на объекты</a></li>
4
<li><a>Вопрос 2: область видимости и event loop</a></li>
4
<li><a>Вопрос 2: область видимости и event loop</a></li>
5
<li><a>Вопрос 3: контекст функции</a></li>
5
<li><a>Вопрос 3: контекст функции</a></li>
6
<li><a>Вопрос 4: прототипы и ключевое слово class</a></li>
6
<li><a>Вопрос 4: прототипы и ключевое слово class</a></li>
7
<li><a>Вопрос 5: строгое равенство</a></li>
7
<li><a>Вопрос 5: строгое равенство</a></li>
8
<li><a>Вместо заключения</a></li>
8
<li><a>Вместо заключения</a></li>
9
</ul><h2>Вопрос 1: объекты и ссылки на объекты</h2>
9
</ul><h2>Вопрос 1: объекты и ссылки на объекты</h2>
10
<p>Почему вместо hey amy получаем результат hey arnold?</p>
10
<p>Почему вместо hey amy получаем результат hey arnold?</p>
11
<h3>Ответ</h3>
11
<h3>Ответ</h3>
12
<p>Вот секрет: { name: 'amy' } !== { name: 'amy' }. Когда JavaScript проверяет равенство или строгое равенство объектов, он использует ссылки на объект. В данном случае мы видим объекты с одинаковыми свойствами. Но для JavaScript это два разных объекта.</p>
12
<p>Вот секрет: { name: 'amy' } !== { name: 'amy' }. Когда JavaScript проверяет равенство или строгое равенство объектов, он использует ссылки на объект. В данном случае мы видим объекты с одинаковыми свойствами. Но для JavaScript это два разных объекта.</p>
13
<p>Чтобы получить ожидаемый результат, нужно использовать такой код:</p>
13
<p>Чтобы получить ожидаемый результат, нужно использовать такой код:</p>
14
<h2>Вопрос 2: область видимости и event loop</h2>
14
<h2>Вопрос 2: область видимости и event loop</h2>
15
<p>Почему код из примера ниже не выводит значения с 0 до 3 по порядку?</p>
15
<p>Почему код из примера ниже не выводит значения с 0 до 3 по порядку?</p>
16
<h3>Проблема</h3>
16
<h3>Проблема</h3>
17
<p>Это неочевидный вопрос. Чтобы правильно ответить на него, нужно понимать область видимости и цикл событий (event loop) в JavaScript.</p>
17
<p>Это неочевидный вопрос. Чтобы правильно ответить на него, нужно понимать область видимости и цикл событий (event loop) в JavaScript.</p>
18
<p>Проблема прячется в нулевой задержке. setTimeout(() => console.log(i), 0) не значит, что колбэк выполнится через 0 миллисекунд. Посмотрим на код через призму event loop:</p>
18
<p>Проблема прячется в нулевой задержке. setTimeout(() => console.log(i), 0) не значит, что колбэк выполнится через 0 миллисекунд. Посмотрим на код через призму event loop:</p>
19
<ol><li>Текущий стек вызовов установлен для первого setTimeout().</li>
19
<ol><li>Текущий стек вызовов установлен для первого setTimeout().</li>
20
<li>window.setTimeout() рассматривается в качестве веб API для выполнения неблокирующих операций ввода-вывода (I/O). Стек вызовов отправляет этот код в веб API. Через 0 миллисекунд колбэк, в данном случае - анонимная функция, отправляется в очередь (queue), но не в стек вызовов.</li>
20
<li>window.setTimeout() рассматривается в качестве веб API для выполнения неблокирующих операций ввода-вывода (I/O). Стек вызовов отправляет этот код в веб API. Через 0 миллисекунд колбэк, в данном случае - анонимная функция, отправляется в очередь (queue), но не в стек вызовов.</li>
21
<li>Поскольку стек вызовов свободен, цикл for переходит ко второму setTimeout() и работает, пока верно условие i < 4.</li>
21
<li>Поскольку стек вызовов свободен, цикл for переходит ко второму setTimeout() и работает, пока верно условие i < 4.</li>
22
<li>Цикл завершается, когда i === 4. Теперь JavaScript выполняет очередь колбэков. Каждый console.log(i) выводит 4.</li>
22
<li>Цикл завершается, когда i === 4. Теперь JavaScript выполняет очередь колбэков. Каждый console.log(i) выводит 4.</li>
23
</ol><p>Ещё одна проблема связана с областью видимости. В примере выше четыре экземпляра setTimeout() работают с одним экземпляром i. Это хорошо иллюстрирует код из примера ниже.</p>
23
</ol><p>Ещё одна проблема связана с областью видимости. В примере выше четыре экземпляра setTimeout() работают с одним экземпляром i. Это хорошо иллюстрирует код из примера ниже.</p>
24
<h3>Ответ</h3>
24
<h3>Ответ</h3>
25
<p>Задачу можно решить несколькими способами. Первый - используйте<a>функцию-обёртку</a>для setTimeout().</p>
25
<p>Задачу можно решить несколькими способами. Первый - используйте<a>функцию-обёртку</a>для setTimeout().</p>
26
<p>Второй способ - просто используйте ключевое слово let вместо var. Переменная, объявленная с помощью var, сохраняется при каждом повторении цикла. А при использовании let при каждом повторении цикла создаётся новая переменная.</p>
26
<p>Второй способ - просто используйте ключевое слово let вместо var. Переменная, объявленная с помощью var, сохраняется при каждом повторении цикла. А при использовании let при каждом повторении цикла создаётся новая переменная.</p>
27
<h2>Вопрос 3: контекст функции</h2>
27
<h2>Вопрос 3: контекст функции</h2>
28
<p>Дан код:</p>
28
<p>Дан код:</p>
29
<p>Почему получаем результат undefined?</p>
29
<p>Почему получаем результат undefined?</p>
30
<h3>Ответ</h3>
30
<h3>Ответ</h3>
31
<p>В коде выше определяется объект dog, в котором два свойства. Мы копируем свойство объекта в константу sayName, а затем вызываем sayName в глобальном контексте. Функция sayName() возвращает window.name, так как в Node.js вызов происходит в глобальном контексте, где typeof window.name === 'undefined'.</p>
31
<p>В коде выше определяется объект dog, в котором два свойства. Мы копируем свойство объекта в константу sayName, а затем вызываем sayName в глобальном контексте. Функция sayName() возвращает window.name, так как в Node.js вызов происходит в глобальном контексте, где typeof window.name === 'undefined'.</p>
32
<p>Проблему можно решить двумя способами: удобным и не очень. Сначала не очень удобный подход: привязываем sayName к контексту dog с помощью bind.</p>
32
<p>Проблему можно решить двумя способами: удобным и не очень. Сначала не очень удобный подход: привязываем sayName к контексту dog с помощью bind.</p>
33
<p>Более удобный подход: сразу вызываем функцию в нужном контексте.</p>
33
<p>Более удобный подход: сразу вызываем функцию в нужном контексте.</p>
34
<h2>Вопрос 4: прототипы и ключевое слово class</h2>
34
<h2>Вопрос 4: прототипы и ключевое слово class</h2>
35
<p>Дан код:</p>
35
<p>Дан код:</p>
36
<p>Почему собака по кличке fido не лает?</p>
36
<p>Почему собака по кличке fido не лает?</p>
37
<h3>Ответ</h3>
37
<h3>Ответ</h3>
38
<p>В выводе появляется ошибка: TypeError: fido.bark is not a function. Есть несколько решений задачи. Вот не самый удобный подход:</p>
38
<p>В выводе появляется ошибка: TypeError: fido.bark is not a function. Есть несколько решений задачи. Вот не самый удобный подход:</p>
39
<p>fido.bark - не функция, но у нас есть функция Dog.bark. Поэтому в примере выше решаем задачу с помощью function.prototype.bind(). Но использование function.prototype.bind() часто приводит к проблемам, поэтому удобнее определить bark() в прототипе Dog:</p>
39
<p>fido.bark - не функция, но у нас есть функция Dog.bark. Поэтому в примере выше решаем задачу с помощью function.prototype.bind(). Но использование function.prototype.bind() часто приводит к проблемам, поэтому удобнее определить bark() в прототипе Dog:</p>
40
<p>И самый удобный вариант: использовать синтаксис ES2015, в частности, ключевое слово class.</p>
40
<p>И самый удобный вариант: использовать синтаксис ES2015, в частности, ключевое слово class.</p>
41
<h2>Вопрос 5: строгое равенство</h2>
41
<h2>Вопрос 5: строгое равенство</h2>
42
<p>Почему код из примера ниже ведёт себя не так, как мы ожидаем?</p>
42
<p>Почему код из примера ниже ведёт себя не так, как мы ожидаем?</p>
43
<h3>Ответ</h3>
43
<h3>Ответ</h3>
44
<p>В коде используется оператор сравнения ==. Этот оператор позволяет сравнивать разные типы данных. Вот что происходит.</p>
44
<p>В коде используется оператор сравнения ==. Этот оператор позволяет сравнивать разные типы данных. Вот что происходит.</p>
45
<p>С аргументом 1 функция isBig() работает как ожидается. При вызове isBig([2]) срабатывает условие thing == 2. При сравнении массива и числа JavaScript преобразует массив в число. Так работает<a>алгоритм сравнения абстрактного равенства</a>: когда мы сравниваем число и объект, а массивы в JS - это объекты, объект преобразуется в число. В нашем массиве один элемент, поэтому [2] == 2.</p>
45
<p>С аргументом 1 функция isBig() работает как ожидается. При вызове isBig([2]) срабатывает условие thing == 2. При сравнении массива и числа JavaScript преобразует массив в число. Так работает<a>алгоритм сравнения абстрактного равенства</a>: когда мы сравниваем число и объект, а массивы в JS - это объекты, объект преобразуется в число. В нашем массиве один элемент, поэтому [2] == 2.</p>
46
<p>Неявные преобразования сложно отслеживать, поэтому при использовании оператора == возможны сюрпризы. Рекомендуется использовать оператор сравнения ===.</p>
46
<p>Неявные преобразования сложно отслеживать, поэтому при использовании оператора == возможны сюрпризы. Рекомендуется использовать оператор сравнения ===.</p>
47
<h2>Вместо заключения</h2>
47
<h2>Вместо заключения</h2>
48
<p>У нас есть<a>репозиторий с реальными тестовыми заданиями</a>от разных компаний. Используйте его, чтобы оценить свой уровень и прокачаться перед собеседованиями. А если у вас остались вопросы по задачам для JavaScript-разработчиков, пишите в комментариях.</p>
48
<p>У нас есть<a>репозиторий с реальными тестовыми заданиями</a>от разных компаний. Используйте его, чтобы оценить свой уровень и прокачаться перед собеседованиями. А если у вас остались вопросы по задачам для JavaScript-разработчиков, пишите в комментариях.</p>
49
<p><em>Адаптированный перевод статьи<a>Typical JavaScript interview exercises (explained)</a>by Maxence Poutord.</em></p>
49
<p><em>Адаптированный перевод статьи<a>Typical JavaScript interview exercises (explained)</a>by Maxence Poutord.</em></p>