Подготовьтесь к собеседованию по JavaScript, изучив вопросы, которые часто задают на технических интервью для позиций junior frontend и junior javascript разработчик. Эта страница содержит краткие ответы на важные вопросы, а также ссылки на ресурсы для дополнительного изучения. Проверьте свои знания основ языка, работы с переменными, функциями, объектами, массивами и другими ключевыми концепциями JavaScript, чтобы быть готовым к любым вопросам на собеседовании.
Ниже представлены вопросы по теме Javascript (источник), которые часто задают на собеседовании. Прочитав вопрос, постарайтесь ответить на него так, как бы вы сделали это во время своего интервью. Под вопросом вы найдете ответ и ссылку на источники раскрывающие тему подробнее.
1) Опишите приём делегирования событий в JS.
Посмотреть ответ
В случае, когда нам нужно обработать событие на нескольких элементах, имеющих общего предка мы «вешаем» слушатель не на элементы, а на предка. После, с помощью event.target, мы можем получить конкретный элемент, на котором было совершено целевое событие и обработать его.
Подробнее тут:
2) Опишите, как работает this в JavaScript? Приведите пример того, как работа с this изменилась в ES6.
Посмотреть ответ
this — ссылка на объект в контексте которого выполняется функция. Другими словами, если внутри функции есть обращение типа this.имя_свойства это значит, что мы обращаемся к свойству объекта в контексте которого эта функция выполняется. Этот механизм позволяет писать функции, которые легко переиспользовать в дальнейшем. Судите сами:
function getName() {
return this.name;
}
var sally = { name: ‘Sally’};
getName.call(sally); // Sally
var megan = { name: ‘Megan’};
getName.call(megan); // ‘Megan
Здесь функция getName ничего не знает об объекте в контексте которого она будет вызвана, тем не менее, превосходно выполняет свою обязаность. Важный момент: контекст выполнения привязывается в момент вызова функции (строка getName.call(sally)). В ES6 была добавлена стрелочная функция, контекст выполнения которой устанавливается не в момент вызова функции, как в примере выше, а в момент определения самой функции.
var getName = () => {
return this.name;
}
var sally = { name: 'Sally'};
getName.call(sally); // undefined
Тут получаем undefined вместо имени, так как функция определена в глобальном скоупе, а в нестрогом режиме, в момент определения стрелочной функции, ее this будет указывать на window (в браузере). В window переменная name не определена, отсюда undefined. Явное определение контекста вызова (.call()) со стрелочными функциями не работает.
Подробнее тут:
3) Опишите, как работает прототипно-ориентированная модель наследования в JS.
Посмотреть ответ
В плане наследования JavaScript работает лишь с одной сущностью: объектами. Каждый объект имеет внутреннюю ссылку на другой объект, называемый его прототипом. У объекта-прототипа также есть свой собственный прототип и так далее до тех пор, пока цепочка не завершится объектом, у которого свойство prototype равно null. По определению, null не имеет прототипа и является завершающим звеном в цепочке прототипов.— Наследование с цепочкой прототипов
При попытке получить доступ к какому-либо свойству объекта, свойство вначале ищется в самом объекте, затем в цепочке прототипов. Поиск ведется до тех пор, пока не найдено свойство с совпадающим именем или не достигнут конец цепочки прототипов.
Подробнее тут:
4) В чем разница между значениями: null, undefined или undeclared? Как бы вы реализовали проверку на эти значения?
Посмотреть ответ
null — пустое значение,
undefined — неопределенное значение
undeclared — переменная не была объявлена, вызов ее вызовет ошибку, вызов typeof покажет undefined (для реализации проверки). Для тестовой переменной «a», проверка может быть реализована следующим образом:
typeof a !== 'undefined' && Boolean(a)
Подробнее тут:
5) Что такое замыкание в JS, и как/для чего его используют?
Посмотреть ответ
Замыкание — прием при котором функция имеет доступ к лексической области видимости своей функции-обертки, которая была выполнена ранее, но не может быть высвобождена из памяти из-за того, что ее собственная область видимости еще используется другой функцией. Лучше всего сказанное будет видно на примере, пример с комментариями тут: https://codepen.io/CHMSupport/pen/JjypeMd?editors=0010
Подробнее тут:
6) Какие конструкции языка вы используете для перебора свойств объекта и элементов массива?
Посмотреть ответ
Для перебора всех (собственных и унаследованных) свойств объекта используется цикл for..in. Для простого перебора элементов массива чаще всего используется функция Array.forEach().
Подробнее тут:
7) Опишите основное различие между методами Array.forEach () и Array.map (), в каких случая вы бы применили каждый из них?
Посмотреть ответ
Метод Array.forEach() перебирает все элементы массива и для каждого вызывает переданную в forEach callback функцию. После отработки ничего не возвращает, при изменении элемента массива в callback функции изменения отражаются в исходном массиве. Array.map() перебирает все элементы массива и для каждого вызывает переданную callback функцию. После отработки возвращает новый массив, равный по длине исходному, который содержит в себе преобразованные элементы массива. При изменении элемента массива в callback функции изменения не отражаются в исходном массиве.
Подробнее тут:
8) Для чего используют анонимные функции в JS ?
Посмотреть ответ
Анонимными называются функции, которые не имеют собственного имени, как следствие, их нельзя сначала объявить, а потом вызвать. Чаще всего такие функции используют в качестве callback функций.
Подробнее тут:
9) В чем заключается различие между host objects и native objects?
Посмотреть ответ
Native objects — объекты определенные спецификацией ECMAScript, например, Object (constructor), Date, Math.
Host objects— объекты, чья роль заключается в создании исполнительного окружения для ECMAScript, например, window, document, location, history.
Подробнее тут:
10) В чем заключается различие между Function Declaration и Function Expression в JavaScript?
Посмотреть ответ
Function Declaration (функция, объявленная в потоке кода) — классическая форма объявление функции.
function sum(a, b) {
return a + b;
}
Function Expression (функциональное выражение) — альтернативный синтаксис для объявления функции.
var sum = function(a, b) {
return a + b;
}
По сути, они делают одно и тоже, но функции, объявленные как Function Declaration могут быть вызваны раньше их места объявления в коде (hoisting), а Function Expression нет.
sum(2, 4);
function sum(a, b) {
return a + b;
}
Подробнее тут:
11) Опишите, что делают Function.call и Function.apply. В чем заключается основное различие между ними?
Посмотреть ответ
Оба метода используются для указания контекста, при вызове функции, к которой применяются. Отличаются синтаксисом, apply более гибкая.
Подробнее тут:
12) За что отвечает Function.prototype.bind ?
Посмотреть ответ
Function.prototype.bind — создает новую функцию, которая при вызове устанавливает в качестве контекста выполнения (this) предоставленное значение, т.е отвечает за вызов функций с другим контекстом.
Подробнее тут:
13) За что отвечают и в чем заключается различие между feature detection, feature inference и User Agent String ?
Посмотреть ответ
- Feature detection, feature inference и User Agent String — это практики определения, существует ли определенная функция веб-технологии в браузере.
- Feature detection — это способ определить, существует ли функция в определенных браузерах.
- Feature inference — предположение: если одна функция присутствует (или нет), соответственно другая тоже будет присутствовать (или нет).
- User Agent String — это текстовая строка, которую отправляет каждый браузер и к которой можно получить доступ через navigator.userAgent. Эта строка содержит в себе информацию о исполнительном окружении.
Подробнее тут:
14) Что такое поднятие (hoisting) в javascript?
Посмотреть ответ
Во время компиляции кода, объявления некоторых переменных и функций поднимаются выше остального кода в пределах своей области видимости. Этот процесс и называется hoisting. Благодаря нему, функция будет успешно вызвана несмотря на то, что в коде ее вызов может идти перед объявлением.
Подробнее тут:
15) Что такое всплытие и погружение событий, в чем заключается разница между ними?
Посмотреть ответ
Всплытие и погружение — это фазы жизненного цикла события. Разница заключается в моменте определения факта наступления события. Изначально, при взаимодействии юзера с элементом интерфейса (клик на кнопку, например) событие погружается от объекта window к целевому элементу (target), после наступает стадия всплытия и событие всплывает от target обратно к window. Так, одно и то же событие может быть перехвачено раньше или позже.
Подробнее тут:
16) Каковы плюсы и минусы расширения встроенных объектов JavaScript?
Посмотреть ответ
Плюсом данного подхода является расширение базового функционала объекта. Прием может быть применен при определении полифилов. В общем случае, расширение поведения встроенных объектов не приветствуется и является плохой практикой (monkey patching). Это нарушает принцип инкапсуляции и засоряет базовые объекты не задокументированной функциональностью.
Подробнее тут:
17) Опишите разницу между == и === в JS ?
Посмотреть ответ
Оба оператора сравнения проверяют тождественность. Различие заключается в том, что двойное равно при сравнении значений неявно приводит (преобразует) типы значений к единому, так строка “1” и цифра 1 при таком сравнении будут равны. Тройное равно не выполняет никаких неявных трансформаций, а значит исходные типы будут иметь значения. Таким образом строка не будет равна числу и не важно что в обоих операндах фигурирует единица.
Подробнее тут:
18) Опишите политику кросс-доменных ограничений (same-origin policy) в контексте JS?
Посмотреть ответ
Same-origin policy (политика одинакового источника) — определяет как сайт (документ/скрипт), загруженный из одного источника может взаимодействовать в браузере с ресурсом (файлом, скриптом, объектом), из другого источника.
Пример:
Если скрипт нашего сайта делает простой запрос (GET) к чужому серверу и получает в ответ файл, при этом в ответе отсутствует заголовок Access-Control-Allow-Origin или в значении этого заголовка отсутствует наш домен, браузер запретит доступ к этому файлу (не даст посмотреть содержимое ответа) из скриптов нашего сайта.
Подробнее тут:
19) Что такое Тернарный оператор, о чем говорит слово “тернарный” ?
Посмотреть ответ
Тернарный оператор — это условный оператор, имеющий форму записи: <условие> ? <истинное выражение> : <ложное выражение>. Тернарным его называют потому, что он имеет три операнда.
Подробнее тут:
20) Что такое strict режим в JS? В чем его преимущества/недостатки?
Посмотреть ответ
Strict (строгий режим)— особый режим работы компилятора, включающий в себя новые возможности и некоторые улучшения обусловленные стандартом ECMAScript 5, при котором изменяется поведение некоторых функций. Включается директивой ‘use strict’. Большинство современных браузеров поддерживают strict режим, однако не все это делают полностью. Строгий режим изменяет семантику, что приводит к погрешностям и ошибкам. Нужно подходить очень внимательно к использованию строго режима и проводить тесты для проверки работоспособности кода как в браузерах, которые поддерживают строгий режим, так и в тех, которые не поддерживают.
Подробнее тут:
21) Каковы основные преимущества / недостатки написания кода на языке компилируемого в JavaScript?
Посмотреть ответ
TypeScript — один из языков, который позволяет писать код, компилируемый в JS.
Среди его преимуществ стоит отметить:
- Поддержка популярными IDE: Sublime Text, Visual Studio Code, WebStorm, Eclipse.
- Реализует многие принципы объектно-ориентированного программирования: модификаторы доступа, наследование, инкапсуляцию и полиморфизм.
- Позволяет быстрее и проще писать сложные решения, которые легче тестировать и развивать благодаря поддержки ООП и строгой типизации.
- Есть система для работы с модулями, классами. Даже есть возможность создавать абстрактные классы.
- TypeScript обратно совместим с JavaScript. Любой код, написанный на JS будет выполнен. Также можно писать смешанный код и он будет валиден.
Недостатки:
- Наличие дополнительных файлов (*.ts, *.d.ts, *.map), что неудобно для небольших проектов.
- Для некоторых браузеров необходима дополнительная настройка консоли для отладки TypeScript.
- TypeScript — язык с неявной статической типизацией: тип может быть описан как any, что отключит приведение к этому типу переменной. d.ts декларации не всегда соответствуют текущей версии библиотеки.
В целом — TypeScript отличный выбор для крупных проектов, поскольку написание занимает больше времени из-за описания деклараций классов и методов. В отсутствии статической типизации в JavaScript, TypeScript — отличное решение.
Подробнее тут:
22) В чем разница между mutable и immutable объектами? Приведите пример immutable объекта в JS.
Посмотреть ответ
Immutable объект — неизменяемый. Объект, состояние которого не может быть изменено после создания. Соответственно, mutable объект может быть изменен после создания. Все примитивы (числа, строки, булевые значения и т.п.) имутабельны.
Подробнее тут:
23) Какие преимущества и недостатки неизменности (immutability) вы можете выделить?
Посмотреть ответ
Преимущества immutability:
- Простое и быстрое отслеживание изменений (например, не нужно отдельно сравнивать значения каждого поля вложенного объекта. Можно просто сравнить ссылки на объекты и отсеять вложенные ветки сравнений).
- Более безопасное использование и тестирование.
Недостатки:
- Создание нового объекта при каждом изменении может стать русурсо-затратной операцией.
Подробнее тут:
24) Как вы можете достичь неизменности (immutability) в собственном коде?
Посмотреть ответ
Использование метода Object.freeze() предотвращает изменение объекта: добавление, удаление или изменение свойств. Использование ключевого слова const вместо var или let не делает константу неизменной, однако предотвращает повторное присваивание нового значения.
Подробнее тут:
25) Опишите разницу между синхронными и асинхронными функциями.
Посмотреть ответ
Синхронные функции — выполняются в том порядке, в котором они написаны в тексте, по очереди.
Асинхронные функции — выполняются отложено, попадая перед выполнением в очередь, что позволяет выполнить их не блокируя основной поток.
Подробнее тут:
26) Что такое цикл событий (event loop) в JS ? Какая разница между «стеком вызовов» (call stack) и «очередью задач» (task queue)?
Посмотреть ответ
Task queue — очередь из завершенных асинхронных задач готовых к синхронной обработке. Из этой очереди задачи будут постепенно перемещены в call stack.
Сall stack — стек вызовов по которому можно определить в каком месте программы сейчас идет ее обработка. Если стек не пуст, значит идет выполнение синхронных задач, а именно, функции, которая находится на верхушке стека.
Event loop — механизм перемещающий готовые к синхронной обработке асинхронные задачи из task queue в call stack.
Подробнее тут:
27) В чем заключаются различия между переменными, созданными с помощью let, var или const?
Посмотреть ответ
- const — переменным объявленным этим оператором должно быть сразу же присвоено значение. В дальнейшем значение не может быть переопределено. Переменная объявленная таким способом не будет видна за пределами блочной области видимости.
- let — значение переменной объявленной этим оператором может быть установлено позже, а так же может быть переопределено в будущем. Переменная объявленная таким способом не будет видна за пределами блочной области видимости. Не доступен hoisting. Не поддерживает повторное объявление.
- var — значение переменной объявленной этим оператором может быть установлено позже, а так же может быть переопределено в будущем. Переменная объявленная таким способом видна за пределами блочной области видимости. Доступен hoisting. Поддерживает повторное объявление.
Подробнее тут:
28) В чем заключаются различия между классом ES6 и конструктором функций ES5?
Посмотреть ответ
- Методы класса являются неперечислимыми свойствами;
- Код внутри класса по умолчанию обрабатывается в строгом режиме;
- Есть различия в синтаксисе;
Подробнее тут:
29) Можете ли вы назвать случай в котором наиболее уместно применение стрелочной функции? Чем этот тип функций отличается от других?
Посмотреть ответ
Стрелочные функции объявляются особой комбинацией символов () => {}. Пожалуй, наиболее уместным вариантом применения стрелочной функций является применение ее как callback функции. Это объясняется основным отличием ее от других типов функций — контекст выполнения стрелочных функций определяется не в момент вызова, а в момент ее объявления (лексический this).
Подробнее тут:
30) Что такое функция высшего порядка?
Посмотреть ответ
Функция высшего порядка — функция которая принимает в качестве аргумента другую функцию или возвращает функцию, т.е работает с другими функциями.
Array.prototype.reduce, Array.prototype.map и Array.prototype.filter — это функции высшего порядка.
Подробнее тут:
31) Приведите пример деструктурирующего присвоения (destructuring assignment) объекта или массива
Посмотреть ответ
Destructuring assignment — механизм извлечения данных из массивов и объектов. При этом используются литералы массива или объекта (в зависимости от того, что разбираем), что увеличивает читабельность и позволяет сразу сказать объект какого типа деструктурируется. Например:
var [firstItem] = arr;
По квадратным скобкам сразу видно, что arr — это массив
Подробнее тут:
32) Приведите пример генерации строки с помощью шаблонной строки ES6.
Посмотреть ответ
Шаблонная строка — строковый литерал, позволяющий использовать выражения внутри строки. Объявляется косыми кавычками.
const variable = 'World!'
console.log(`Hello ${variable}`);
Подробнее тут:
33) Что такое каррирование в JS?
Посмотреть ответ
Каррирование (currying) — преобразование функций с множеством аргументов в набор вложенных функций с одним аргументом. После вызова такой функции с передачей ей аргумента, она возвращает новую функцию, ожидающую следующего аргумента и так до получения результата.
Подробнее тут:
34) Каковы преимущества использования spread syntax и чем он отличается от rest syntax?
Посмотреть ответ
Spread — оператор состоящий из трех точек. Преимущество — в короткой форме записи. Отличие — в зависимости от места применения этот оператор трактуется как spread или rest оператор. Rest используется для деструктуризации коллекций (разделение на отдельные элементы), а spread, наоборот, для соединения отдельных значений в массив.
let arr = ['one', 'two', 'three', 'four'];
// destructuring with three dots (rest)
let [first, second, ...rest] = arr;
console.log(first); // 'one'
console.log(second); // 'two'
console.log(rest); // ['three', 'four']
// concatenation with three dots. Same syntax but different behaviour
const restored = [first, second, ...rest];
console.log(restored) //['one', 'two', 'three', 'four'];
Подробнее тут: