Вопросы для собеседования JavaScript-разработчика
Что такое ECMAScript?
ECMAScript — это спецификация, стандарт скриптовых языков программирования, он является основой JS, поэтому любые изменения ECMAScript отражаются на JS. ECMAScript сам по себе - это не язык программирования. А вот JavaScript - это язык программирования, реализующий стандарт ECMAScript. Чем отличаются JavaScript и ECMAScript? ECMAScript 2015, 2016, 2017, 2018, 2019, 2020, 2021
Какие различия между ES5 и ES6?
ECMAScript 5 (ES5) — 5-е издание ECMAScript, выпущенное в 2009 году. Поддерживается современными браузерами практически полностью.
ECMAScript 6 (ECMAScript 2016, ES6) — 6-е издание ECMAScript, выпущенное в 2015 году. Частично поддерживается большинством современных браузеров.
Несколько ключевых отличий двух стандартов:
1. Стрелочные функции и интерполяция в строках
// В новом стандарте можно сделать так:
const greetings = (name) => {
return `hello ${name}`;
}
// и даже так:
const greetings = name => `hello ${name}`
2. Ключевое слово const
Константы в JavaScript отличаются от констант в других языках программирования. Они сохраняют неизменной только ссылку на значение. Таким образом, вы можете добавлять, удалять и изменять свойства объявленного константным объекта, но не можете перезаписать текущую переменную, в которой лежит этот объект.
const NAMES = [];
NAMES.push("Jim");
console.log(NAMES.length === 1); // true
NAMES = ["Steve", "John"]; // error
3. Блочная видимость
Переменные, объявленные с помощью новых ключевых слов let
и const
имеют блочную область видимости, то есть недоступны за пределами {}
-блоков. Кроме того, они не поднимаются, как var
-переменные.
4. Параметры по умолчанию
Теперь функцию можно инициализировать с дефолтным значением параметров. Оно будет использовано, если параметр не будет передан при вызове.
function multiply (a, b = 2) {
return a * b;
}
multiply(5); // 10
5. Классы и наследование
Новый стандарт ввел в язык поддержку привычного синтаксиса классов (class
), конструкторы (constructor
) и ключевое слово extend
для оформления наследования.
6. Оператор for-of для перебора итерируемых объектов в цикле
7. spread и rest операторы
const obj1 = { a: 1, b: 2 }
const obj2 = { a: 2, c: 3, d: 4}
const obj3 = {...obj1, ...obj2}
8. Обещания (Promises)
Механизм для обработки результатов и ошибок асинхронных операций. По сути, это то же самое, что и коллбэки, но гораздо удобнее. Например, промисы можно чейнить (объединять в цепочки).
const isGreater = (a, b) => {
return new Promise ((resolve, reject) => {
if(a > b) {
resolve(true)
} else {
reject(false)
}
})
}
isGreater(1, 2)
.then(result => {
console.log('greater')
})
.catch(result => {
console.log('smaller')
})
9. Модули
Способ разбития кода на отдельные модули, которые можно импортировать при необходимости.
import myModule from './myModule';
Синтаксис экспорта позволяет выделить функциональность модуля:
const myModule = {
x: 1,
y: () => {
console.log('This is ES5')
}
}
export default myModule;
Что такое операторы spread и rest?
Spread оператор (оператор расширения) "берет" каждый отдельный элемент итерируемого объекта (массив) и "распаковывает" его в другой итерируемый объект (массив).
К итерируемым объектам можно отнести все, что можно перебрать с помощью цикла for..of
. Большая часть задач, где приходится использовать оператор spread, касается массивов и строк.
Так будет выглядеть создание одного общего массива с помощью оператора spread:
const tvSeriesOne = ['Ozark', 'Fargo', 'Dexter'];
const tvSeriesTwo = ['Mr. Robot', 'Barry', 'Suits'];
const tvSeries = [...tvSeriesOne, ...tvSeriesTwo];
console.log(tvSeries);
// [ "Ozark", "Fargo", "Dexter", "Mr. Robot", "Barry", "Suits" ]
Оператор rest …
(три точки) похож на оператор spread, но выполняет противоположную функцию.
Spread забирает каждый элемент из массива и распаковывает в новый массив. Оператор rest забирает каждый элемент из массива и создает из них новый массив.
Есть 2 типа задач, где оператор rest используется чаще всего – в функциях и в процессе деструктуризации.
function buyPizza(price, ...rest) {
console.log(price); // 500
console.log(rest);
// Array(4) [ 3, 10, 6, 20 ]
}
buyPizza(500, 3, 10, 6, 20);
const pizza = ['Pepperoni', 2222, 5, 6, 10, 30, 1];
const [name, id, ...rest] = pizza;
console.log(name); // Pepperoni
console.log(id); // 2222
console.log(rest);
// [ 5, 6, 10, 30, 1 ]
7 трюков с Rest и Spread операторами при работе c JS объектами
Что такое деструктуризация?
Деструктуризация в JavaScript позволяет извлечь данные из массива или свойства объекта и присвоить их отдельным переменным. Деструктуризация удобна тем, что позволяет не писать лишний код для доступа к данным внутри объектов/массивов по индексам или ключам.
Деструктуризация массива:
let array = [1, 2, 3];
let [x, y, z] = array;
console.log(x); // 1
console.log(y); // 2
console.log(z); // 3
Деструктуризация объекта:
let user = {
name: "Василий",
lastname: "Пупкин",
age: 30
};
let {name, lastname, age} = user;
console.log(name); // "Василий"
console.log(lastname); // "Пупкин"
console.log(age); // 30
Вы не знаете деструктуризацию, пока
Перечислите типы данных JavaScript
- undefined
- null
- boolean
- number
- string
- bigint
- object
- symbol
(ES6)
«Сложно о простом». Типы данных JS. В поисках истины примитивов и объектов
Глубокий JS. В память о типах и данных
Что такое Map?
Map
– это коллекция ключ/значение наподобие Object
, но с более удобным и декларативным API и некоторыми функциональными особенностями. Например, Map
позволяет использовать ключи любого типа.
Методы и свойства:
new Map()
– создаёт коллекцию.
Map.prototype.set(key, value)
– записывает по ключу key
значение value
.
Map.prototype.get(key)
– возвращает значение по ключу или undefined
, если ключ key
отсутствует.
Map.prototype.has(key)
– возвращает true, если ключ key
присутствует в коллекции, иначе false
.
Map.prototype.delete(key)
– удаляет элемент (пару «ключ/значение») по ключу key
.
Map.prototype.clear()
– очищает коллекцию от всех элементов.
Map.prototype.size
– возвращает текущее количество элементов.
let map = new Map();
map.set("1", "str1"); // строка в качестве ключа
map.set(1, "num1"); // цифра как ключ
map.set(true, "bool1"); // булево значение как ключ
// помните, обычный объект Object приводит ключи к строкам?
// Map сохраняет тип ключей, так что в этом случае сохранится 2 разных значения:
alert(map.get(1)); // "num1"
alert(map.get("1")); // "str1"
alert(map.size); // 3
Для перебора коллекции Map
есть 3 метода:
Map.prototype.keys()
– возвращает итерируемый объект по ключам,
Map.prototype.values()
– возвращает итерируемый объект по значениям,
Map.prototype.entries()
– возвращает итерируемый объект по парам вида [ключ, значение], этот вариант используется по умолчанию в for..of
.
В отличие от обычных объектов, в Map
перебор происходит в том же порядке, в каком происходило добавление элементов.
Что такое Set?
Set
– это особый вид коллекции: «множество» значений (без ключей), где каждое значение может появляться только один раз.
Его основные методы это:
new Set(iterable)
– создаёт Set
, и если в качестве аргумента был предоставлен итерируемый объект (обычно это массив), то копирует его значения в новый Set
.
Set.prototype.add(value)
– добавляет значение (если оно уже есть, то ничего не делает), возвращает тот же объект Set
.
Set.prototype.delete(value)
– удаляет значение, возвращает true
, если value
было в множестве на момент вызова, иначе false
.
Set.prototype.has(value)
– возвращает true
, если значение присутствует в множестве, иначе false
.
Set.prototype.clear()
– удаляет все имеющиеся значения.
Set.prototype.size
– возвращает количество элементов в множестве.
Основная «изюминка» – это то, что при повторных вызовах set.add()
с одним и тем же значением, оно добавляется в коллекцию лишь единожды.
Set
имеет те же встроенные методы для перебора коллекции, что и Map
:
Set.prototype.keys()
– возвращает перебираемый объект для значений,
Set.prototype.values()
– то же самое, что и set.keys()
, присутствует для обратной совместимости с Map
,
Set.prototype.entries()
– возвращает перебираемый объект для пар вида [значение, значение], присутствует для обратной совместимости с Map
.
Ускоряем JavaScript-код с использованием типа данных Set
Что такое цикл событий?
Цикл событий - это механизм, на каждом тике выполняющий функции из стека вызовов и, если он оказывается пустым, перемещающий задачи из очереди задач в стек вызовов для выполнения. Лежит в основе функционирования любого JavaScript-движка. Стек вызовов - это структура данных (первым вошел, последним вышел), используемая для отслеживания порядка выполнения функций в текущем контексте (области видимости). Очередь задач - это структура данных (первым вошел, первым вышел), используемая для отслеживания выполнения асинхронных функций, готовых оказаться в стеке вызовов. Что ты такое, Event Loop? Или как устроен цикл событий в браузере Chrome Как работает JS: цикл событий, асинхронность и пять способов улучшения кода с помощью async / await
Что такое область видимости?
Область видимости — это область, ограничивающая доступ к переменным и функциям внутри себя, как бы инкапсулирующая их. JS имеет три типа областей видимости: глобальная, функциональная и блочная (ES6).
Глобальная — переменные и функции, объявленные в глобальном пространстве имен, имеют глобальную область видимости и доступны из любого места в коде.
Функциональная — переменные, функции и параметры, объявленные внутри функции, доступны только внутри этой функции.
Блочная — переменные, объявленные с помощью ключевых слов let
и const
, доступны только внутри блока {}
, в котором были объявлены.
Область видимости — это также набор правил, по которым осуществляется поиск переменной. Если переменной не существует в текущей области видимости, ее поиск производится выше, во внешней по отношению к текущей области видимости. Если и во внешней области видимости переменная отсутствует, ее поиск продолжается вплоть до глобальной области видимости. Если в глобальной области видимости переменная обнаружена, поиск прекращается, если нет — выбрасывается исключение. Поиск осуществляется по ближайшим к текущей областям видимости и останавливается с нахождением переменной. Это называется цепочкой областей видимости (Scope Chain).
Область видимости в JavaScript и «поднятие» переменных и объявлений функций
Области видимости в JavaScript
Какое значение у "this"?
this
ссылается на значение объекта, который в данный момент выполняет функцию.
В конструкторе класса, например, this
будет указывать на создаваемый экземпляр.
На самом верхнем уровне исполнения this
будет указывать на глобальный объект (window
в браузере).
Function.prototype.call
и Function.prototype.apply
принимают в качестве первого аргумента объект, который будет являться значением this
внутри функции.
Function.prototype.bind
позволяет создать новую функцию с подмененным контекстом (this
).
Стрелочные функции не имеют собственного значения this
. Они копируют значение this
из внешнего лексического окружения.
Ключевое слово this в javascript — учимся определять контекст на практике
Ключевое слово this в JavaScript. Полное* руководство