Работа мечты в один клик 💼

💭Мечтаешь работать в Сбере, но не хочешь проходить десять кругов HR-собеседований? Теперь это проще, чем когда-либо!
💡AI-интервью за 15 минут – и ты уже на шаг ближе к своей новой работе.
Как получить оффер? 📌 Зарегистрируйся 📌 Пройди AI-интервью 📌 Получи обратную связь сразу же!
HR больше не тянут время – рекрутеры свяжутся с тобой в течение двух дней! 🚀
Реклама. ПАО СБЕРБАНК, ИНН 7707083893. Erid 2VtzquscAwp
1. Какие типы данных есть в JavaScript?

Number – число. Тип Number в JavaScript может хранить как целые числа, так и числа с плавающей точкой.
BigInt – используется для представления целых чисел произвольной длины, превышающих 2^53 – 1. BigInt создается с помощью добавления n в конец целочисленного литерала или путем вызова функции BigInt(), которая создает BigInt из строк, чисел и т.д.:
// Создание BigInt путем добавления n в конец целочисленного литерала
const bigInt1 = 1234567890123456789012345678901234567890n;
// Создание BigInt путем вызова функции BigInt()
const bigInt2 = BigInt("1234567890123456789012345678901234567890");
// Создание BigInt из числа
const bigInt3 = BigInt(10); // Это то же самое, что и 10n
// Сложение
console.log(1n + 2n); // 3n
// Деление
console.log(5n / 2n); // 2n
String – строка (последовательность символов), например, "JavaScript – главный язык интернета"
.Строки записываются с использованием кавычек, можно использовать одинарные или двойные кавычки.
Boolean – логический (булев) тип, который может принимать
значения true
(истина) или false
(ложь).
Object – объект. Это значение в памяти, на которое возможно сослаться с помощью идентификатора. Объект может расцениваться как набор свойств. Значения свойств могут иметь любой тип, включая другие объекты, что позволяет строить сложные, разветвленные иерархии данных.
null – специальное значение, которое представляет «ничего», «пусто», или «неизвестное значение».
undefined – это значение присваивается переменной, если она была объявлена, но не получила значения.
Symbol – это уникальный и неизменяемый тип данных, который можно использовать в качестве идентификатора для свойств объекта.
2. В чем состоит различие между == и ===?

В JavaScript операторы ==
и ===
используются для сравнения
двух значений, но они работают по-разному:
==
проверяет на абстрактное равенство, то есть он
преобразует типы данных перед сравнением – например, если вы сравниваете строку
с числом, JavaScript преобразует строку в число перед сравнением. Если строка
не может быть преобразована в число, она преобразуется в NaN, что возвращает
false
. Если оба операнда имеют разные типы данных, но они могут быть
преобразованы в один и тот же тип данных и имеют одно и то же значение,
оператор ==
вернет true
:
var a = 10;
console.log(a == 20); // false
console.log(a == "1o"); // false
console.log(a == "10"); // true
===
проверяет на
строгое равенство, то есть он не выполняет преобразование типов данных. Если два значения имеют разные типы данных, оператор ===
вернет
false
, даже если они имеют одно и то же значение. Если оба операнда имеют одинаковый тип данных и одинаковое значение, оператор ===
вернет true
:
var x = 10;
console.log(x === "10"); // false
console.log(x === 10); // true
3. Какие способы объявления переменных есть в JavaScript?
В JavaScript есть четыре способа объявления переменных:
myVariable = 5;
var myVariable = 5;
let myVariable = 5;
const myVariable = 5;
myVariable = 5;
– неявное объявление переменной. Оно создает
глобальную переменную myVariable и присваивает ей значение 5, что может привести
к ошибкам в строгом режиме:
"use strict";
myVariable = 5; // ReferenceError: myVariable is not defined
var myVariable = 5;
– явное
объявление переменной с использованием ключевого слова var
. Область видимости переменной
myVariable может быть функциональной или глобальной, если она объявлена вне
функции. Недостаток var
состоит в том, что ее область видимости не ограничивается
блоком, в котором используется переменная:
function example() {
var myVariable = 1;
if (true) {
var myVariable = 2; // Переопределяет myVariable из внешнего блока
console.log(myVariable); // Выводит 2
}
console.log(myVariable); // Выводит 2
}
example();
let myVariable
= 5;
– явное объявление переменной с использованием ключевого слова let
. Область
видимости такой переменной ограничивается блоком, в котором она объявлена – на уровне
функции она не видна:
function example() {
let myVariable = 5;
if (true) {
let myVariable = 25; // Это новая переменная myVariable, которая видна только внутри этого блока
console.log(myVariable); // Выводит 25
}
console.log(myVariable); // Выводит 5
}
example();
const myVariable
= 5;
– это явное объявление переменной с использованием ключевого слова const
.
Переменная myVariable объявляется в области видимости блока, как и let
. Однако,
в отличие от let
, переменная myVariable является неизменяемой – ее значение не
может быть изменено после объявления, за одним исключением: если значение
является объектом или массивом, его свойства или элементы могут быть изменены,
но сама переменная все равно остается неизменяемой:
const myVariable = 5;
console.log(myVariable); // Выводит 5
myVariable = 10; // TypeError: Assignment to constant variable.
const myObject = { key: "value" };
myObject.key = "otherValue"; // Это допустимо
console.log(myObject.key); // Выводит "otherValue"
const myArray = [];
myArray.push("A"); // Это допустимо
console.log(myArray); // Выводит ["A"]
4. В чем разница между null и undefined?

В JavaScript и null, и undefined представляют отсутствие значения, но они используются в разных контекстах и имеют разные семантические значения.
undefined
– присваивается переменной, когда она объявлена, но ей не
присвоено конкретное значение:
var testVar;
console.log(testVar); // Выводит undefined
console.log(typeof testVar); // Выводит undefined
null
– специальное значение, которое представляет «ничего», «пусто» или «неизвестное
значение». Присваивается переменной вручную, чтобы указать, что она не должна
иметь значения. Например, если нужно очистить значение переменной, можно установить
его в null
:
var testVar = 5;
console.log(testVar); // Выводит 5
var testVar = null;
console.log(testVar); // Выводит null
console.log(typeof testVar); // Выводит object
5. Чем стрелочные функции отличаются от обычных?

Стрелочные функции позволяют использовать упрощенный синтаксис при создании небольших функций-обработчиков. У них есть некоторые ограничения по сравнению с обычными функциями:
Стрелочные функции не могут использовать объект arguments. В обычных функциях этот объект содержит все переданные при вызове аргументы:
function sum() {
console.log(arguments); // { '0': 1, '1': 2, '2': 3 }
}
sum(1, 2, 3);
const sumArrow = () => {
console.log(arguments); // ReferenceError: arguments is not defined
}
sumArrow(1, 2, 3);
У стрелочных функций другой синтаксис записи. Они
записываются короче, используя стрелку =>
и не требуя ключевого слова
function
:
function sum(a, b) {
return a + b;
}
const sumArrow = (a, b) => a + b;
У стрелочных функций нет собственного контекста this. Вместо этого контекст берется из внешней области видимости:
const myObject = {
text: "JavaScript - очень простой язык",
description: function() {
setTimeout(() => {
console.log(this.text);
}, 1000);
}
};
myObject.description(); // Выводит "JavaScript - очень простой язык"
Стрелочные функции нельзя использовать как конструкторы с
ключевым словом new. То есть, из них нельзя создавать объекты при помощи
оператора new
:
const myFunction = () => {};
const newFunction = new myFunction(); // TypeError: myFunction is not a constructor
6. Что такое замыкание?
Замыкание (closure) в JavaScript – это комбинация функции и лексического окружения, в котором эта функция была определена. Такая функция имеет доступ к переменным внешней функции, даже после того, как внешняя функция завершила выполнение:
function createAdder(x) {
return function(y) {
return x + y;
};
}
const add5 = createAdder(5);
const add10 = createAdder(10);
console.log(add5(2)); // Выводит 7
console.log(add10(2)); // Выводит 12
7. Что такое шаблонные строки (литералы)?
Шаблонные строки (template literals) в JavaScript – это
новый способ работы со строками, введенный в ECMAScript 6 (ES6). Они обозначаются
обратными кавычками `
вместо одинарных или двойных кавычек. Шаблонные строки
позволяют создавать многострочные строки без необходимости использования
специальных символов или конкатенации строк:
let multilineString = `Это строка номер 1
Это строка номер 2
Это строка номер 3`;
console.log(multilineString);
Шаблонные строки также поддерживают интерполяцию строк, что
позволяет вставлять выражения прямо в строку. Эти выражения заключаются в
фигурные скобки ${expression}
и вычисляются при создании строки:
let name = "Василий Пупкин";
let dailyBonus = 0;
let greeting = `Привет, ${name}! Тебе начислен ежедневный бонус - ${dailyBonus + 5} руб`;
console.log(greeting); // Выводит: Привет, Василий Пупкин! Тебе начислен ежедневный бонус - 5 руб.
8. Что такое Map и Set в JavaScript?
Map и Set – это два типа коллекций, которые были введены в ECMAScript 6 (ES6). Они предоставляют более гибкие и мощные способы работы с наборами данных по сравнению с обычными объектами и массивами.
Map – это коллекция, которая состоит из пар ключ-значение, подобно объектам. Основное отличие Map от объектов заключается в том, что Map запоминает порядок добавления пар и позволяет использовать в качестве ключей данные любых типов:
let user1 = { name: 'Егор' };
let user2 = { name: 'Марина' };
let userRoles = new Map();
userRoles.set(user1, 'администратор');
userRoles.set(user2, 'редактор');
console.log(userRoles.get(user1)); // Выводит: администратор
console.log(userRoles.get(user2)); // Выводит: редактор
При желании в Map в качестве ключей можно использовать функции:
function sayHello() {
console.log('приветствие');
}
function sayGoodbye() {
console.log('прощание');
}
let functionMap = new Map();
functionMap.set(sayHello, 'Привет!');
functionMap.set(sayGoodbye, 'До свидания!');
console.log(functionMap.get(sayHello)); // Выводит: Привет!
console.log(functionMap.get(sayGoodbye)); // Выводит: До свидания!
Set – это множество, в котором каждое значение может появляться только один раз. Дубликатов в Set нет:
const mySet = new Set();
mySet.add('яблоко');
mySet.add('апельсин');
mySet.add('апельсин'); // Это не добавит 'апельсин' второй раз, так как такое значение уже есть
console.log(mySet.has('яблоко')); // Выводит: true
console.log(mySet.has('апельсин')); // Выводит: true
console.log(mySet.has('банан')); // Выводит: false
9. Как проверить наличие свойства в объекте?

В JavaScript есть два основных способа проверить наличие
свойства в объекте – метод hasOwnProperty
и оператор in
.
Метод hasOwnProperty()
возвращает true, если указанное
свойство является прямым свойством объекта, и false в противном случае. Этот
метод не проверяет свойства в цепочке прототипов объекта. Оператор in
возвращает true, если указанное свойство существует в объекте, независимо от
того, является ли оно собственным свойством или унаследовано:
const book = {
title: "Великий Гэтсби",
author: "Ф. Скотт Фицджеральд",
year: 1925
};
console.log(book.hasOwnProperty("title")); // true
console.log("title" in book); // true
console.log("year" in book); // true
console.log("language" in book); // false
10. Как получить доступ к свойствам объекта?
В JavaScript есть два основных способа доступа к свойствам объекта: статический (с использованием точечной нотации) и динамический (с использованием квадратных скобок).
Точечная нотация позволяет напрямую получить доступ к свойству объекта, используя имя свойства. Скобочная нотация позволяет динамически получить доступ к свойству объекта с использованием квадратных скобок:
const movie = {
title: "Крестный отец",
director: "Фрэнсис Форд Коппола",
year: 1972
};
console.log(movie['title']); // Крестный отец
console.log(movie.director); // Фрэнсис Форд Коппола
Скобочная нотация использует интерполяцию и особенно полезна, если имя свойства неизвестно заранее или когда оно хранится в переменной:
var propertyName = "title";
var book = {
title: "Анна Каренина",
author: "Лев Толстой",
year: 1877
};
console.log(book[propertyName]); // Анна Каренина
11. Какие основные методы работы с массивами есть в JavaScript?

Oсновные методы для работы с массивами – forEach, filter, map и reduce.
Метод forEach
выполняет функцию для каждого элемента в
массиве. Он не возвращает ничего, но позволяет выполнять действия с каждым
элементом массива. Применяется, когда нужно выполнить некоторые операции над
каждым элементом, но не нужно создавать новый массив:
const array = ['один', 'два', 'три'];
array.forEach(element => console.log(element));
/*
вывод:
один
два
три
*/
Метод filter
создает новый массив, включающий только те
элементы исходного массива, для которых функция обратного вызова возвращает
true. Используется, когда нужно отфильтровать массив, чтобы включить только
определенные элементы:
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter(number => number % 2 === 0);
console.log(evenNumbers); // [2, 4]
Метод map
создает новый массив, который состоит из
результатов применения функции к каждому элементу исходного массива. Применяется,
когда нужно преобразовать каждый элемент массива:
const numbers = [1, 2, 3, 4, 5];
const squares = numbers.map(number => number * number);
console.log(squares); // [1, 4, 9, 16, 25]
Метод reduce
выполняет функцию для каждого элемента массива,
накапливая результат в одном значении. Используется, когда нужно объединить все
элементы массива в одно значение, например, вычислить сумму всех чисел в
массиве:
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(sum); // 15
12. Какие способы создания объектов есть в JavaScript?
Объекты
JavaScript создаются с помощью функции-конструктора, литеральной
нотации объекта, класса и метода Object.create()
.
Функция-конструктор – это специальная функция, которую можно
использовать для создания объектов с определенными свойствами и методами.
Функция-конструктор используется с ключевым словом new
:
function Movie(title, director, year) {
this.title = title;
this.director = director;
this.year = year;
}
const movie = new Movie('Дракула Брэма Стокера', 'Фрэнсис Форд Коппола', 1992);
console.log(movie); // { title: 'Дракула Брэма Стокера', director: 'Фрэнсис Форд Коппола', year: 1992 }
Литеральная нотация объекта позволяет создать объект, указав
его свойства и значения внутри фигурных скобок {}
:
const movie = {
title: 'Сердце Ангела',
director: 'Алан Паркер',
year: 1987
};
console.log(movie); // { title: 'Сердце Ангела', director: 'Алан Паркер', year: 1987 }
Классы позволяют создавать объекты с помощью синтаксиса, похожего на классы в других языках программирования:
class Movie {
constructor(title, director, year) {
this.title = title;
this.director = director;
this.year = year;
}
}
const movie = new Movie('Шоссе в никуда', 'Дэвид Линч', 1997);
console.log(movie); // { title: 'Шоссе в никуда', director: 'Дэвид Линч', year: 1997 }
Метод Object.create() позволяет создать новый объект, используя существующий объект в качестве прототипа для нового объекта. Этот метод принимает два аргумента: прототип и объект свойств. Объект свойств определяет свойства нового объекта и их атрибуты configurable
, enumerable
, writable
и value
:
const moviePrototype = {
title: 'Интерстеллар',
director: 'Кристoфер Нолан',
year: 2014
};
const movie = Object.create(moviePrototype, {
title: {
value: 'Интерстеллар',
writable: true,
enumerable: true,
configurable: true
},
director: {
value: 'Кристoфер Нолан',
writable: true,
enumerable: true,
configurable: true
},
year: {
value: 2014,
writable: true,
enumerable: true,
configurable: true
}
});
console.log(movie); // { title: 'Интерстеллар', director: 'Кристoфер Нолан', year: 2014 }
13. Что такое Promise (промис)?

Промис (Promise) — специальный объект JavaScript, который используется для написания и обработки асинхронного кода. Он имеет три состояния:
- pending – начальное состояние, означает, что асинхронная операция еще не завершена.
- fulfilled – операция успешно завершена.
- rejected – операция завершена с ошибкой.
Промисы создаются с помощью конструктора new Promise()
. Этот
конструктор принимает в качестве аргумента функцию, которая выполняет
асинхронную операцию. Функция принимает два аргумента resolve
и reject
, которые
используются для изменения состояния промиса. Если асинхронная операция
завершена успешно, вызывается resolve
, если произошла ошибка, вызывается reject
:
let promise = new Promise((resolve, reject) => {
// асинхронная операция
setTimeout(() => {
resolve("Результат асинхронной операции");
}, 1000);
});
Промисы позволяют обрабатывать результаты асинхронных операций, используя методы .then()
и .catch()
. Метод .then()
принимает два аргумента: функцию обратного вызова, которая будет вызвана при успешном выполнении промиса, и функцию обратного вызова, которая будет вызвана при ошибке. Метод .catch()
используется для обработки ошибок, которые могут произойти при выполнении промиса:
let promise = new Promise((resolve, reject) => {
// асинхронная операция
setTimeout(() => {
resolve("Результат асинхронной операции");
}, 1000);
});
promise
.then(result => {
console.log("Результат: " + result);
})
.catch(error => {
console.log("Ошибка: " + error);
});
Промисы можно связывать в цепочки, что позволяет
выполнять несколько асинхронных операций последовательно. Для этого результат
каждого промиса передается в следующий промис в цепочке. Это делается с помощью
метода .then()
:
let promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Результат первой операции");
}, 1000);
});
let promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Результат второй операции");
}, 2000);
});
promise1
.then(result1 => {
console.log("Результат первой операции: " + result1);
return promise2;
})
.then(result2 => {
console.log("Результат второй операции: " + result2);
});
14. Что такое async/await и как они используются?

Async/await – это синтаксис JavaScript, который облегчает
работу с промисами. Ключевое слово async
перед функцией означает, что функция
всегда возвращает промис. Ключевое слово await
используется внутри асинхронных
функций и заставляет JavaScript ожидать, пока промис не будет выполнен, прежде
чем продолжить выполнение кода:
async function example() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("Сделано!"), 2000)
});
let result = await promise; // жди выполнения промиса
alert(result); // Сделано! появляется в подтверждении действия
}
example();
Надо отметить, что await
нельзя использовать вне асинхронной
функции. Например, этот код приведет к ошибке:
async function fetchDataFromApi() {
const res = await fetch('https://v2.jokeapi.dev/joke/Programming?type=single');
const json = await res.json();
console.log(json.joke);
}
await fetchDataFromApi(); // SyntaxError: await is only valid in async functions
Чтобы решить эту проблему, можно обернуть вызов в другую асинхронную функцию:
async function fetchDataFromApi() {
const res = await fetch('https://v2.jokeapi.dev/joke/Programming?type=single');
const json = await res.json();
console.log(json.joke);
}
async function init() {
await fetchDataFromApi();
console.log('Принес новый анекдот!');
}
init();
15. Как проверить, является ли объект массивом?
Для такой проверки можно использовать встроенный метод
Array.isArray()
. Этот метод принимает объект в качестве аргумента и возвращает
true
, если объект является массивом, и false
в противном случае:
let arr = [1, 2, 3];
console.log(Array.isArray(arr)); // true
let obj = { a: 1, b: 2 };
console.log(Array.isArray(obj)); // false
16. Что делает оператор расширения?

Оператор расширения ...
разворачивает итерируемые элементы в
отдельные элементы, что удобно для передачи аргументов, объединения
массивов/объектов и добавления новых свойств в объекты. Используется:
В функциях, где ожидаемое количество аргументов для вызова равно нулю или более:
function sum(a, b, c) {
return a + b + c;
}
let numbers = [1, 2, 3];
console.log(sum(...numbers)); // 6
В литералах массива:
let arr1 = [1, 2, 3];
let arr2 = [...arr1, 4, 5];
console.log(arr2); // [1, 2, 3, 4, 5]
В литералах объекта, где количество пар ключ-значение должно быть равно нулю или более:
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let combined = [...arr1, ...arr2];
console.log(combined); // [1, 2, 3, 4, 5, 6]
let obj1 = { a: 1, b: 2 };
let obj2 = { c: 3, d: 4 };
let combinedObj = { ...obj1, ...obj2 };
console.log(combinedObj);// { a: 1, b: 2, c: 3, d: 4 }
Для преобразования строки в массив символов:
const str = "JavaScript";
const charArray = [...str];
console.log(charArray); // ['J', 'a', 'v', 'a', 'S', 'c', 'r', 'i', 'p', 't']
Для преобразования числа в массив цифр и наоборот:
const num = 12345;
const numArray = [...num.toString()].map(Number);
console.log(numArray); // [1, 2, 3, 4, 5]
const number = Number(numArray.join(''));
console.log(number); // 12345
Для копирования объектов:
let obj = {
name: 'Марк',
age: 25
};
let newobj = { ...obj };
console.log(newobj); // {name: 'Марк', age: 25}
17. Как выполняется клонирование объекта?
Если объект не содержит вложенных объектов, как в
приведенном ниже примере, для клонирования можно использовать оператор
расширения ...
или метод Object.assign()
:
const obj = {
firstName: 'Василий',
lastName: 'Пупкин'
};
const copy1 = {...obj};
console.log(copy1); // {firstName: 'Василий', lastName: 'Пупкин'}
// или
const copy2 = Object.assign({}, obj);
console.log(copy2); // {firstName: 'Василий', lastName: 'Пупкин'}
Если объект содержит вложенные объекты, нужно выполнить глубокое копирование. Относительно медленный вариант – с использованием JSON:
const obj = {
data: {
id: 1
}
};
const copy = JSON.parse(JSON.stringify(obj));
Другой вариант – с использованием метода cloneDeep
из библиотеки lodash:
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.20/lodash.min.js"></script>
<script>
const original = {
name: 'Максим',
details: {
age: 30
}
};
// Вызываем метод Lodash напрямую
const copy = _.cloneDeep(original);
copy.name = 'Марина';
copy.details.age = 32;
console.log(original);
console.log(copy);
</script>
18. Как изменить контекст функции?
Изменить контекст функции можно с помощью методов bind()
,call()
и apply()
.
Метод bind()
возвращает новую функцию с привязанным контекстом:
function myFunction() {
return this;
}
const obj = {name: 'Лев Толстой'};
const newFunction = myFunction.bind(obj);
console.log(newFunction()); // {name: 'Лев Толстой'}
Метод call()
принимает последовательность аргументов, а apply()
принимает массив аргументов в качестве второго параметра:
function sum(a, b) {
return a + b;
}
const numbers = [1, 2];
console.log(sum.call(null, 1, 2)); // 3
console.log(sum.apply(null, numbers)); // 3
19. Что такое тернарный оператор и как он работает?

Тернарный оператор – это сокращенная форма записи if-else. Он называется тернарным, потому что является единственным оператором в JavaScript, который принимает три аргумента. Синтаксис тернарного оператора:
условие ? выражение_если_истинно : выражение_если_ложно
Условие – любое условие, которое возвращает true
или false
.
Выражение для истинного условия – что нужно вернуть, если условие истинно.
Выражение для ложного условия – что нужно вернуть, если условие ложно.
Например:
let accessAllowed;
let age = 16;
accessAllowed = (age > 18) ? "Доступ открыт" : "Доступ закрыт";
// аналогично записи через if-else:
if(age > 18) {
accessAllowed = "Доступ открыт";
} else {
accessAllowed = "Доступ закрыт";
}
console.log(accessAllowed); // выведет Доступ закрыт
20. Что такое деструктуризация?
Деструктуризация в 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
Продолжение следует.
Комментарии