HR - скрининг и подтверждение опыта
Почему вы решили покинуть компанию (ищите новое место)?
Проекты, которые мы пилим, у нас уже на стадии завершения, и компания хочет больше упор сделать на менеджмент, и по этому в скором времени наверное через 2-3 месяца it-отдел распустят и по этому попутно ищу новое место.
Расскажи про текущий проект, сколько у вас человек, что за продукт вы разрабатываете, что ты делаешь на фронте что успешного смог реализовать за это время
Если говорить про проекты, то у нас их несколько - это основной сайт по бронированию номеров различных отелей в Индонезии; а также есть различные внутренние проекты, например свой аналог traveLine, когда человек бронирует у нас номер, то отправляется запрос на бронь и менеджеры, администраторы могут видеть на какой срок был забронирован номер. А также есть продукту связанные с аналитикой - какие номера самые прибыльные, сколько мы получили выручки за определенный квартал и прочее.
Команда разработки состоит у нас из 3 фронтов, 2 беков, 1 project-менеджера, дизайнера и аналитика.
Ну если говорить лично про меня, то основной продукт по бронированию номеров в отелей разработал я. У нас было не раз общение с project-manager и дизайнером, то как они хотят видеть проект. Пока дизайнер рисовал макет, я улучшал продукт, так как первая версия нашего сайта была не очень - у нее было много ошибок и недочетов и их нужно было улучшать. Как собственно говоря я улучшал продукт - переписывал большинство технологий на современный лад - например классовые компоненты улучшал на функциональные, javascript на typescript, улучшил версию webpack и многое многое другое, там достаточно много было работы
Вы целенаправленно откликнулись на нашу вакансию? / Чем вас заинтересовало наша вакансий / Чего к нам перевело?
Я обратил внимание, что условие, которое вы предлагаете мне подходит, а именно работа гибрид /удаленно и по тк РФ, также я посмотрел продукты над которыми вы работаете, и они тоже мне подходят
Какая ЗП у вас на текущей работе / Какие у вас зарплатные ожидания?
На текущем место у меня 220т, рассматриваю я от 250т рублей, но если проект куда меня направят будет интересным, то зарплатные ожидания могу снизить
У вас есть предложения от других компаний?
Да, у меня есть один оффер от Ifellow и на следующей недели будет пару технических собесов, думаю до конца следующей недели уже решу куда. Я сейчас рассматриваю в основном либо ТК-РФ либо по ИП, а у вас как раз так.
С какими гибкими методологиями вы знакомы?
У нас двухнедельные спринты, где мы планируем обсуждаем предстоящие задачи, даем оценку времени за сколько решим ту или иную задачу, помимо спринтов у нас также есть ежедневные созвоны. Работали по scrum.
Как вы относитесь к работе в сверхурочное время?
Зависит от ситуации, но в основном нейтрально - например бывают такие момент, что есть какая-то фича, которую прям необходимо реализовать до релиза и я могу спокойно немного задержатся. Но если это на постоянной основе и неоплачиваем, то негативно
Как вы оцениваете сроки выполнения задачи?
Зависит от сложности самой задачи, обычно когда я вижу задачу, в начале обдумываю ее, обсуждаю что хотят от меня получить, изучаю проект и если есть какие-то стоперы, то беру и их в условия и так получаю оценку в задачи
Расскажите о ситуации, когда вы не укладывались в сроки?
Обычно если я не успеваю завершить задачу в срок, то я предупреждаю об этом либо тим-лида либо проджект менеджера, и мы после созвона обсуждаем мои блоккеры и как их можно решить. Бывали много случаев как мы решали данные задачи - либо ко мне кто-то приходил на помощь и мы вместе думали как решить ту или иную задачу. Либо редкий кейс, но я работал сверхурочно, то есть знал, что это важная фитча и хотел поскорее его завершить.
Расскажите о самых сложных проблемах, над которыми вы работали. Расскажите в подробностях, как вы их решали
Когда я только пришел в ИТМО, меня попросили сделать редактор текста согласно определенной библиотеке, тогда половина команды уволилась, а другая половина была в отпуске из фронтов. Сроки были крайне малые, там просили сделать основных 4 расширения - жирность, курсив, надстрочный, подстрчоный текст и два дополнительных - гиперссылка и тултип. Основной трудностью было разобраться в механизме как работает данный редактор текста, и как добавлять туда дополнительные фитчи, но после пару дней внутри редактора текста и в гитхабе где разбирались те или иные вопросы - за 2 недели я смог реализовать основные расширения, и еще 2 недели ушло на реализацию оставшихся потому что они были неочивидные и сложные для понимания реализации. Также был опыт в полном переделывания легаси компонента из классовых компонентов в функциональных, там был достаточно большой проект со старым кодом и его было трудно поддерживать и компания решила его модернизировать на современный лад
Каким достижением на прошлой работе вы можете гордиться?
Если про общую говорить, то благодаря полному переписыванию проекта с классов на функциональность и добавлением новых фитч, мы смогли увеличить кол-во пользователей из 2-3 заходов на сайт, до 150-200 ежедневных заходов. Также можно вспомнить, что у нас была проблема с организованностью кода, все писали по-разному. Я внедрил документацию по написанию кода и предложил единую архитектуру, что улучшило читаемость всего проекта.
- Спросить про заработную плату (зп)?
- Сколько длится испытательный срок и после испыт.срока увеличивается ли заработная плата или она остается такой же? - 1-3 месяца норм испытательного срока. Обычно во время испыталке платят меньше на 10%-20%, а после уже по окладу, которому договаривались.
- Как часто поднимают заработную плату? - раз в пол года норм.
- Как я буду оформлен в компании? - Самозанятый, ИП, ГПХ, ТК РФ или без оформления
- Заключается ли NDA (соглашение о неразоглашении)?
- Выдают ли оборудование или мне необходимо со своим придти уже? - Если выдают то какое
- Можете рассказать по подробнее о проекте(ах) с которыми придется работать?
- Есть ли у компании какие-то цели на ближайшие годы? - Запуск новых проектов например
- Сколько времени приблизительно понадобится на принятие решение найма меня?
- Сколько будет этапов на собеседование?
- Если устраивается на позицию сеньора нужно уточнить сколько человек у тебя будет на попечении
- Сколько человек на проекте(ах)?
- Бывают ли переработки в компании и как часто бывают?
- По какому методологию работает - Scrum, canban, или таск треккер?
Я решил добавить данный пункт потому что в некоторых компаниях есть дополнительное секция - подтверждение опыта в разработки и оно как мне кажется подходит для данного раздела идеально, так как косвенно затрагивает вопросы, которые hr спрашивал. Собственно вот сами вопросы
- Расскажи про свое последнее место работы
- Как у вас устроен процесс разработки в команде?
- Есть ли процесс код-ревью?
- Есть ли регулярные встречи? Если да, то какие?
- Какие технологии вы используете?
- Используете ли стейт-менеджеры? Какие и почему?
- Как вы тестируете свой код? Автоматизируете ли вы этот процесс? Какие виды тестов пишите?
- Сталкивался ли ты с проблемами при автоматизации тестов? Если да, то с какими?
- Как в вашем проекте происходит релиз кода в production? Как тестировался код перед релизом?
- Каким образом выстроено взаимодействие между бэкенд- и фронтенд-разработчиками? Распараллеливаете ли вы задачи? Если да, то как вам это удается?
- Есть ли у вас на проекте CI/CD? Если да, то что в него входит? Кто за него отвечает?
- Есть ли у тебя опыт написания собственных пайплайнов для автоматизации? Если да, то расскажи о нем
- Каким образом вы отслеживаете ошибки в production? Есть ли у вас мониторинги? Сбор логов с прода? Если да, то расскажи, как это устроено
- Измеряете ли вы скорость работы сайта? Если да, то как?
- Сколько пользователей у вашего сайта? Какая в среднем нагрузка?
- Опираетесь ли вы на пользовательские метрики при разработке новых фичей? Какие это метрики? Как они собираются?
- Есть ли у вас дизайнеры? Как выстроен процесс взаимодействия между дизайнерами и фронтенд-разработчиками?
- Есть ли у тебя опыт написания кода для бэкенда? Если да, то какой?
- Сталкивался ли ты с проблемами со скоростью работы сайта? Как ты их решал?
- Представь себе ситуацию: к тебе приходит заказчик и говорит «сайт тормозит». Какие твои действия?
- Представь себе ситуацию: ты не укладываешься в дедлайн по важной задаче, которую от тебя очень ждут. Какие твои действия?
- Какими своими профессиональными достижениями ты гордишься?
- Какую самую интересную/сложную/запоминающуюся задачу ты решал?
- Было ли такое, что ты самостоятельно проявил инициативу на работе и как-то повлиял на проект/продукт/процесс? Расскажи про такой случай
- Бывали ли у тебя конфликты в команде? Если да, то расскажи про них. Из-за чего они возникли и как ты их решал?
- Почему ты сейчас ищешь работу?
- Как бы ты описал свое идеальное место работы?
HTML (HyperText Markup Language)-язык гипертекстовой разметки
Что такое HTML и опишите базовую структуру HTML-страницы?
HTML (Hypertext Markup language) – язык гипертекстовой разметки. Он используется для отображение веб-страницы в браузере. Базовая структура HTML состоит из
-
<!Doctype html>, которая указывается в самом начале и сообщает browser, что мы используем последнюю версию HTML5 -
<head>- содержит информацию о документе, в нем может хранится заголовок, шрифты, стили и meta-tag. Meta-tag - дополнительная информация о веб-странице, которая затем передает информацию поисковой системе. Например:
- кодировка: UTF-8;
- имя автора страницы
- описание страницы;
- ключевые слова для продвижения.
meta name="viewport"- сообщает браузеру, как именно обрабатывать размеры страницы и изменять её масштаб.
`<meta name="viewport" content="width=device-width, initial-scale=1">`
1. meta name="viewport" - сообщает браузеру о том, как именно обрабатывать размеры страницы,
и изменять её масштаб.
2. content="width=device-width - ширина области просмотра, которая задает ширину в
соответствии с девайсом
initial-scale=1 - начальный масштаб страницы: 1.0 (обычно определяет).
Свойство max-scale/min-scale – определяет как пользователям разрешено
увеличивать или уменьшать страницу. А если мы хотим запретить
масштабирование используем user scalable: 0
<body>– содержит всю разметку html документа. Именно это разметка и будет отображается в браузере.
Есть ли у HTML – элементов свои дефолтные специфичные стили?
или: какие источники стилей применяется к веб-странице помимо наших.
Да, конечно есть, практически во всех:
- У заголовках - это размер шрифта, отступ и жирность;
- У списков – маркеры и цифры;
Однако стоит упомянуть, что в разных браузерах они могут отмечаться по разному, у кого-то размер шрифта побольше например, обычно прибегают к обнулению стилей (reset.css) или делает для всех стилей одинаковые стили (normalize.css)
Что такое inline стиль? Можно ли его переопределить?
Inline стиль – это стиль, который находится внутри определенного тега. У него вес 1000 и это самый большой вес селектора, которого крайне трудно переопределить. Переопределить его можно только с помощью !important,
Что такое семантика? Какие семантические тэги вы знаете?
Раньше все программисты писали с помощью дивах и span, однако с появлением семантических тегов в HTML5, то много что поменялось. и они помогают браузеру и поисковым системам, анализировать и понимать структура, содержимое нашего веб-приложения. А также он повышает доступность (accessibility). Например для слабовидящих - screen-reader читает текст делая на каких-то словах акцент по типу strong или em. Вместо картинки, screen-reader читает поясняющий текст внутри img тега alt.
Какая разница между тэгами `strong` и `em` и `b` и `i`?
Теги: strong и b (bold) - делает текст жирным,
Теги em (emphasis) и i (italic) - делает его курсивным.
Основное отличие одни из них семантические (strong, em), а другие не семантические (b, i) - когда screen-reader читает теги strong и em он делает на них небольшой акцент, в то время как на b и i он не делает акцента
Как семантически верно сверстать навигационное меню?
Через nav > ul > li > a
Как можно скрыть элемент разметки не используя CSS и JS?
В html есть для этого специальный атрибут: hidden, однако это не самая лучшая практика влиять на страницу через разметку, так как он не виден не только для пользователя, но и для screen-reader. Данный тег глобальный и его можно добавлять везде. Его аналог в css – это display: none
Какой тег использовать для того, чтобы сверстать кнопку?
Обычная кнопка: <button>Кнопка</button>
Кнопка подтверждения формы, используется:
<button type=”submit”>Иная кнопка</button>
<input type=”submit” value=”button>
<input type = “button”>
Типы списков в HTML?
<ul>- маркированный список. Каждый элемент списка отмечается маркером: li;<ol>- нумерованный список. Каждый элемент списка отмечается маркером: li;- Список определений, состоит он из следующих тегов:
dl– основная обертка,dt– определения иdd– поясняющий текст;
Для чего используются тэги tr, th, td?
Данные теги используются внутри другого тега: <table>, а тот в свою очередь необходим для создания таблиц:
<tr> (table row) – контейнер для создания строки таблицы
<th> (table-header) – предназначен для создания одной ячейки таблицы в виде заголовка
<td> (table-data) – ячейка таблицы
<table>
<tr>
<td>Hi, I'm your first cell.</td>
<td>I'm your second cell.</td>
<td>I'm your third cell.</td>
</tr>
</table>
Для какого тэга используется атрибут alt и зачем он нужен?
Он пишется в img. Если вдруг у нас картинка не отобразится на странице, то вместо него отобразится (поясняющий) текст, тот который мы указали в alt.
Данный атрибут также полезен для людей с ограниченными возможностями, когда страница будет читаться screen-reader, то при чтении и будет зачитываться то, что находится в alt. (Помимо этого использование атрибута улучшается accessibility (доступной страницы) так как различные screen-readers при чтении веб-страницы зачитывают его. В результате пользователи с ограниченными возможностями понимает контекст используемого изображения)
Она еще необходимо для валидации
Что такое валидация HTML-разметки? И какие типы проверок HTML документа вы знаете?
Валидация HTML-разметки — это проверка написания кода согласно W3S (World Wide Web Consortium). Это платформу в которую мы можем перетащить наш html-код, чтобы он проверил его на ошибки. Ошибки могут быть разного вида, где то закрывающий тег не указал, где-то к картинке в атрибутах альт не указал.
Почему хорошей практикой считается располагать link для подключения CSS стилей внутри тэга head, а script для подключения JS ставить перед закрывающим тегом body
-
Тег link внутри шапки сайта описана в спецификации HTML. Если в head находится stylesheet, то страница загружается быстрее
-
Сначала подключаются html и css при первой загрузке страницы и они должны находится в самом header. После того как все загрузилось используется js, если мы поставим js в самое начало, то оно будет блокировать (загрузку) от рисовку html. Размещение скриптов внизу позволяет сперва распарсить и показать пользователю весь HTML, а затем уже добавить к нему логику.
Разница между `script`, `script async` и `script defer`? (Асинхронный и отложенный)
Обычно браузеры загружают script синхронно, во время разбора документа. Поэтому принято добавлять скрипты в конец документа, перед </body>, чтобы они не тормозили загрузку страницы. Но при помощи атрибутов defer и async можно явно управлять порядком загрузки и выполнения скриптов.
-
<script async src="...">=> скрипт выполняется параллельно c чтением html документа. Он не будет ждать когда произойдет загрузка и отображение веб-страницы. Он хорош для независимых скриптов, например счётчиков и рекламы, порядок выполнения которых не играет роли. -
<script defer src="...">– указывает браузеру, что скрипт должен быть выполнен после того, как как произойдет полная загрузка html.
На практике defer используется для скриптов, которым требуется доступ ко всему DOM-дереву или если важен их порядок выполнения.
Дополнительный вопрос: есть несколько идущих подряд скриптов с атрибутом async. Порядок их загрузки и выполнения будет соблюден ? А с defer
Для чего используют data-атрибуты?
Появился он в HTML-5 и data-атрибуты позволяют хранить дополнительную информацию прямо в тегах HTML-кода. Например: data-size, Также с помощью определенного синтаксиса можно легко стилизовать его. [data-age="46"] {}
Для чего используется элемент datalist?
Используется для создания выпадающего списка, которое можно выбирать при наборе в текстовом поле и datalist с атрибутом id должен полностью совпадать с содержимым: "" с input элементом атрибутом лист.
<label form="select-animal">Who is the strongest animal?:</label>
<input list='animals' id="select-animal" placeholder="type here... " />
<datalist id="animals">
<option value ="Elephant">
<option value ="Tiger">
<option value ="Zebra">
<option value ="Lion">
</datalist>Типы `input` элементов в HTML? (Необходимо перечислить их и назвать особенности)
Input – элемент необходим для общения (коммуникации) с пользователям, он предназначен для получение вводимых данных. У него есть атрибут type
input type = "text" - предназначенный для ввода букв, цифр и специальных символов.
input type = "password" – используется для паролей. Его особенность - отображаются как звездочки.
input type = "email" - предназначен для ввода “email” пользователи.
input type = "number" - позволяет вводить только числовое значение ну и при фокусировке на нем открывается клавиатура, содержащие только цифры.
input type = "button" (input type = "submit") – поле для ввода. В этом случае превращается в кнопку, с помощью "submit” можно даже отправить форму.
input type = "checkbox" (radio) button - заменяет поле ввода на специальные элементы либо квадрат с галочкой либо кружок с точкой.
input type day month daytime local - предназначены для ввода даты.
Представьте HTML5 как открытую веб-платформу. Из каких блоков состоит HTML5?
• Семантика (позволяет более точно описать из чего состоит контент);
• Стилизация (позволяет создавать более сложные темы оформления);
• Доступ к устройствам (позволяет взаимодействовать с различными устройствами ввода и вывода);
• Связанность (позволяет общаться с сервером);
• Офлайн и хранилище (позволяют страницам хранить данные локально на клиентской стороне и более эффективно работать в offline);
• Мультимедиа (создание и подключение видео и аудио);
• 2D/3D-графика и эффекты (позволяет расширить возможности презентации);
• Производительность и интеграция (обеспечивает большую скорость оптимизации и лучшее использование аппаратных средств).
CSS (Cascading Style Sheets) - каскадная таблица стилей
Что такое CSS и для чего он используется? Что такое CSS-правило?
CSS (Cascading Style Sheets - каскадная таблица стилей), необходим для стилизации html-разметки. Существует несколько вариантов добавление стилей. Например:
-
inline-style - это когда внутри html тега пишется style и вес его слишком большой.
-
Внешние стили - когда в html, в хедере пишем стиль
-
Создаем отдельный файл со стилями и подключаем через links, в элементе head,
<link rel="stylesheet" type="text/css" href="style.css">
Мы выносим стили в отдельный css-файл, чтобы отделить логику и структуру веб-страницы (написанную на HTML) от описания её внешнего вида. Такое разделение дает больше гибкости и возможностей, а также позволяет уменьшить сложность и повторяемость в структурном содержимом.
СSS-правило относится к синтаксису CSS. Синтаксис состоит из селектора и блока объявлений, в котором описываются свойства со значениями:
CSS-правило сообщает браузеру, что и каким образом будет отформатировано тот или иной селектор. Например: изменить цвет текста заголовка, выделить изображение красной рамкой, установить ширину блока в 200 пикселей и т.д.
Что такое селектор? И какие селекторы существуют? Специфичность селекторов
Селектор - это теги, которые необходимы для стилизации HTML-кода. Селектор сообщает браузеру к какому элементу(ам) будет применен стиль. Они делятся на простые (исп 1 селектора) и составные (объединяет простые селектора). Например к простым можно отнести - селектор класса, id или tag, * - универсальный селектор, который будет применять стиль ко всем.
К составным: групповой селектор (когда мы пишем через запятую селектора), что в свою очередь избавляет от дублирования; есть также псевдокласс (определяет его особое состояние) и pseudo-elements (позволяет стилизовать определённую часть выбранного элемента). Есть селектор потомка, который будет стилизоваться только внутри родительского элемента без вложенности.
Также стоит отметить, что есть такое понятие как специфичность селекторов. И из-за специфичность селекторов могут некоторые стили не применяться (конфликт стилей). Например у нас есть два css-правила один написанный через id, а другой через класс, и применится тот стиль, который написан в id - так как его вес больше. Если говорить иначе, то стили которые мы пишем внутри тега html - то есть inline-style имеют вес 1000, их переопределить можно через important; вес у ID - 100; классы, pseudo-classes и атрибуты имеют вес 10, а элемент, звездочки и псевдоэлемент - 1.
li => 1
ul li 1 + 1 => 2
#main .item 100 + 10 => 110
h1 + *[href= “test”] 10 + 1 => 11
#test p 100 + 1 => 101
li. item.main 1 + 10 + 10 => 21
#test => 100
ul ol li .item 1 + 1 + 1 + 10 => 13
ul ol+li 1 + 1 + 1 => 3
a:hover 1 + 10 => 11
Стоит отметить, что если специфичность одинаковая то срабатывает последний стиль
Разница между классом и идентификатором (id) в CSS? Когда что использовать
-
id - должен быть уникальным и встречаться на странице 1 раз. Вес id - 100; и id у элемента должен быть только один. Для добавлении логики
-
class - можно задавать и использовать много раза. Вес класса - 10; у одного элемента может быть несколько классов. Для добавление стилей
Что такое pseudo-elements (псевдоэлементы) и pseudo-classes (псевдоклассы)?
- Псевдоэлемент – это кл.слово, которое добавляется к селектору, тем самым позволяет стилизовать определенную часть выбранного элемента.
::first-letter – позволяет стилизовать первую букву в тексте, например сделав его красным;
::first-line - позволяет стилизовать первую строку в тексте, например сделать все буквы - большими через uppercase();
::placeholder - позволяет стилизовать input или textarea, изменив там цвет на красный;
::marker - позволяет стилизовать списки маркированные;
::before и ::after – который позволяет добавлять дополнительный контент до и после основного контента. Например мы можем написать кавычки перед и после основного контента;
- Псевдокласс - это кл.слово, которое добавляется к селектору и работает с его состоянием. Например у нас есть абстрактная ссылка с помощью:
:hover - мы можем изменить при наведении на ссылку;
:active - по клику мы можем изменять его цвет;
:visited - после того как зашли изменить цвет не на фиолетовый а на ярко-голубой;
:disabled - может любой input поле disable;
Например у нас есть 3 блока, и мы хотим скрыть 3 или первый и второй мы можем использовать nth-last-child();
Что такое box-sizing в СSS? Блочная модель CSS?
Данное свойство определяет как вычисляется общая ширина и высота элемента. По умолчанию у box-sizing стоит content-box, он в свою очередь считает только ширину и высоту, если . Например у нас ширина 100 пикселей, и мы хотим добавить padding-left: 10px, ширина будет уже 120px и это ширина будет постоянно расти, увеличивать блок
Однако второе значения работает иначе, он считает вместе с высотой и шириной. Если в первом случае оно не считалось, то во втором оно считает. Тот же самый пример ширина 100 пикселей, добавим padding-left: 20 px - и изменения будут происходит внутри блока, а ширина останется таким же.
Если мы начали говорить про box-sizing: border-box, то стоит упомянуть блочную модель CSS. Это правила, по которым браузер определяет размер элемента на странице, его ширину и высоту. Он состоит из следующих свойств:
- содержимое (это может быть текст, изображение, видео и др.), ширина (содержимого), которого задается свойством width, а высота (содержимого) через height;
- padding — внутренний отступ;
- border - границы
- margin - внешние отступы
Что такое схлопывания внешних отступов (margin collapsing)?
Схлопывание границ (margin collapsing) - это когда margin-top и bottom объединяются в один общий отступ. Например у нас есть 2 margin: 10 и 50 пикселей. И будет не 60 пикселей отступа, а 50.
Существует достаточно много способов как решить данную проблему. Например написав вместо margin - paddings или через псевдокласс last-child с нулевым margin
Разница между относительными и абсолютными величинами?
-
Абсолютные единицы имеют фиксированное значение. К нему относятся: px (
пиксели), cm (сантиметры), mm (миллиметр), in (дюймы). -
Относительные определяют размер какого-либо элемента относительно другого размера. К нему относятся:
-
em (п.с. относительно родительского элемента, если установлен размер шрифта родительского элемента равный 18 пикселей, то 1em будет равно 18 пикселям)
-
rem (п.с. относительно корневого элемента. Например: в html, font-size будет 16 пикселей. Если мы каком-то блоке напишем 2 рема, то будет 32 пикселя. Он унаследуется от корневого элемента)
-
vh (viewport height) и vw (viewport width) - это высота и ширина области просмотра (окна браузера), где 1vh = 1% от высоты viewport, а 1vw = 1% от ширины viewport.
-
% - процент от значения того же свойства у родительского элемента (например, width: 50% будет равна половине ширины родителя).
Типы позиционирования в CSS?
-
Static position (нормальное / статическое позиционирование) - значение по умолчанию, свойства top, right, bottom, left игнорирует;
-
Relative position (относительное позиционирование) - элемент сдвигается относительно его обычного положения. Его можно менять с помощью top, right, bottom, left.
-
Absolute position (абсолютное позиционирование) - исчезает из того места в котором был и позиционируется заново. Остальные элементы располагаются так, как буд-то этого элемента и не было. Координаты: top, right, bottom, left отчитываются от ближайшего позиционированного родителя или от всего документа. Он работает с z-index.
-
Fixed position (фиксированное позиционирование) - когда нам необходимо зафиксировать какой-то контейнер в одном месте и при scroll он будет идти вместе с нами.
-
Sticky position (липкое позиционирование) - похож на фиксированное позиционирование. Отличие от него, то что он крепится в рамках какого-то блока, а не всего документа. Нельзя позиционировать элемент по горизонтали, а может только по вертикале через свойства (top, bottom) - относительно вверха низа страницы
Дополнительный вопрос: Что такое z-index, как он работает, с какими position он работает?
Он работает с относительным, абсолютным и фиксированным позиционирование. Когда нам необходимо какой-то элемент поставить поверх другого элемента, то с помощью z-index мы можем это сделать. У него работают как положительные, так и отрицательные значения. Максимальное число 9 999 999 999
Свойство display - какие значение принимают и как они работают?
-
None - это когда элемент не показывается на экране вообще;
-
Block - это блочные элементы, которые располагаются вертикально один за другим. Он стремится расширится на всю доступную ширину;
-
Inline - они располагаются на одной строке, последовательно одним за одним. Ширина и высота по содержимому и менять высоту и ширину нельзя;
-
Inline-block - элемент является строчным, но при этом ему можно задавать ширину и высоту;
-
Flex;
-
Grid;
-
Table;
-
List-item
Есть еще глобальные ключевые слова:
-
initial - стандартное поведение свойства. То есть говорит браузеру использовать значение по умолчанию для заданного CSS-свойства. Например, для свойства color значение initial всегда будет black;
-
inherit - наследует свойство из родительского элемента;
-
unset - если оно наследуется, то ведет себя как inherit, а если нет, то как initial;
-
revert - сбрасывает стили до первоначального заданных браузером значений;
Расскажите про поток документов в CSS
Это порядок вывода элементов на страницу. В обычном виде все блоки выводятся в том порядке, в котором они записаны внутри HTML-документа без стилей.
нормальный поток документа - это тот поток документа у которого нет стилей вообще
Как с помощью CSS определить, поддерживается ли свойство в браузере?
Для этого есть специальная директива @supports(){}. Она проверяет, поддерживается ли свойство, правило, или css-селектор в браузере. В круглых скобках пишется условие проверки, а в фигурных скобках код, который выполнится, если условие поддерживается. Пример:
Какие фильтры есть в CSS?
Blur (px,em)- размытие по Гауссу к исходному изображению. Чем больше радиус, тем больше размытие. Начальное значение: 0Brightness (%, 10-дробь)- изменяет яркость изображение. Также чем больше, тем ярче. Начальное значение: 1Contrast (%, 10-дробь)- регулирует контрастность между самым темным и светлым участком фона. Начальное значение: 100%, ниже будут уменьшать контрастность, а выше будут увеличиватьDrop-shadowСмещение по оси Х смещение по оси Y размытость растяжение цвет тениGrayscale (%, 10-дробь)- извлекает все цвета из картинки, делая на выходе черно-белое изображение.
Для чего используется ключевое слово currentColor в CSS?
Current color работает как переменная, , которая всегда содержит текущее значение свойства color элементаесли у нас у кнопки есть цвет синий, то он наследует этот цвет. И если поменяется основной цвет, то поменяются и все остальные
Что такое CSS-атрибут (attr)?
CSS-атрибут (attr) - с помощью данной CSS-функции, мы можем брать значении из HTML атрибутов и добавлять в стили
// HTML
<button data-tooltip="Добавить в корзину">Купить</button>
<a href="#" title="Перейти на главную">Главная</a>
// CSS
button::after {
content: attr(data-tooltip);
display: none;
}
a::before {
content: "Подсказка: " attr(title); // Выводим значение title в подсказке
}Что такое CSS-спрайт? И для чего он используется?
CSS-спрайт — это техника, когда множество небольших изображений (обычно иконок) объединяются в один большой файл.
Плюсы:
- Сокращает кол-в запрос на сервер - из 20 картинок условно отправляем 1
- Значительно ускоряет загрузку страницы
- Бандл становится меньше
Что такое вендорные префиксы (vendor prefix)? И для чего они используются?
Вендорные префиксы – это приставка к названию CSS – свойства, которые позволяют браузерам внедрять экспериментальные фичи до того, как они полностью стандартизированы и готовы для использования
Вендорные префиксы — это специальные приставки, которые браузеры добавляют к экспериментальным или нестандартным CSS-свойствам
-o- Opera
-moz- Mozilla
-ms- Microsoft
-webkit- Apple
Работают они следующим образом: для элемента прописывается CSS свойство в прямом виде для браузеров, которые его понимают. Следом за ним через точку с запятой перечисляется то же самое свойство, но с разными вендорными префиксами для разных браузеров. Браузер из такого кода интерпретирует только то свойства, которое написано под него, а написанные для других браузеров игнорирует. Может быть вопрос: где можно посмотреть, как поддерживается то или иной свойство? - Ответ: https://caniuse.com/flexbox
Разница между reset.css / normalize.css
Практически все html-элементы содержат дефолтные стили: размер и жирность шрифта, внутренние и внешние отступы и др. Основной нюанс заключается в том, что каждый браузер применяет разные стили. И для того, чтобы вверстка выглядела одинокого, используют обнуления стилей: reset.css / normalize.css
Они подключаются в самом начале css-файла. И reset.css сбрасывает все дефолтные стили на ноль, а normalize – нормализует (стабилизирует) для различных браузеров – сохраняет дефолтные стили и делает их везде одинаковым. Недостатком reset.css – это то, что мы стили пишем заново. История: https://www.youtube.com/watch?v=KGYmOlNteas
→ Задачи по HTML и CSS
Как сделать с помощью html и css: круг, прямоугольник, квадрат, треугольник, стрелу
Круг - border-radius: 50%
Прямоугольник - ширина должна быть больше высоты
Квадрат - ширина и высота должны быть одинакового размера
Треугольник
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
Стрела
Стрела направо - transform: rotate(-45deg); Стрела налево - transform: rotate(135deg); Стрела вверх - transform: rotate(-135deg); Стрела вниз - transform: rotate(45deg);
Перечислите способы центрирования блока
- Через флексбокс:
display: flex;
justify-content: center
align-items: center
- Через margin: 0 50; а также margin: auto
- Через абсолютное позиционирование
- Через vertical-align: middle
Как изменить направления оси flex-контейнера?
display: flex; flex-direction: column
Как сделать анимацию бесконечно повторяющейся?
Animation-duration: infinite
У нас есть список из пяти скажем так блоков, как сделать так, чтобы 5 блок был не виден
Через псевдокласс nth-child или last-child
Как сделать кастомный чекбокс
→ Методологии: БЭМ, DRY, KISS, YAGNI
БЭМ - методология, которая расшифровывается как блок, элемент, модификатор, разработан он яндексам и решает проблему naming, то есть делает имена CSS-классов максимально информативными для разработчиков, но это больше рекомендации naming.
DRY (Don't repeat yourself) - Не повторяли то, что уже написал, вынеси его в отдельную функцию и используй в разных местах.
KISS (Keep it short simple / keep it simple, stupid) - делайте код было легким для понимания, а не сложным.
YAGNI (You ain't gonna need it) - не стоит писать код, который может не понадобится в будущем.
GIT - система контроля версий для отслеживания изменений в коде
- Какие команды знаешь в git?
Git add, commit -m ..., push, reset,
- Чем отличается git merge и git rebase
- Что делает git pull
- Что делает git ammend
- Как можно минимизировать кол-во merge конфликтов ? git
- Расскажи про git хуки
- Расскажи что знаешь про методологии git flow и github flow
JavaScript
Перечислите типы данных в JavaScript?
В JavaScript существует 8 типов данных, их можно разделить на примитивные и ссылочные. К примитивным относятся: string; number; bigInt; boolean; symbol (unical id); null и undefined. А к ссылочному относится object (объекты).
Функции, массивы также относится к объекту из-за прототипа и прототипного наследования
Если говорить про объекты то они передаются по ссылке, а примитивы по значению
Доп.вопрос: В чем разница между null и undefined?
В том, что Undefined - это когда переменная объявлена, но мы ей не присвоено значение, а null - когда мы присвоили значение специально, и как бы говорим, что у нас есть переменная и она пустая.
Кстати при нестрогом сравнение undefined и null дает true, а при строгом false, а также при сравнение null == 0 дает false
Доп.вопрос: Как мы можем определить к какому типу данных относится та или иная переменная?
А определить тип данных можно с помощью typeOf.
Typeof возвращает следующие значения - "undefined", "boolean", "number", "string", "bigint", "symbol", "function", "object"
console.log(typeof 0) // * number
console.log(typeof true) // * boolean
console.log(typeof 'Javascript') // * string
console.log(typeof undefined) // * undefined
console.log(typeof Math) // * object, так как встроенный глобальный объект
console.log(typeof Symbol('JS')) // * symbol
console.log(typeof null) // * object
console.log(typeof function() {}) // * function
console.log(typeof NaN) // * number
console.log(typeof typeof 100) // * stringДоп.вопрос: JavaScript статически, или динамически типизированный язык?
Динамически типизированный язык, так как происходит автоматическое преобразование типов
Доп.вопрос: Как превратить любой тип данных в булевое и разница между явным и неявным преобразованием?
В JS мы можем явно преобразовать типы, всего их три: String(), Boolean(), Number() - и все они являются функциями.
Чтобы превратить тип данных в булевый можно использовать:
- Функцию Boolean(null)
- !! (Двойное логическое не),
Допилить идею: Если мы применим его к не пустой строке, то оно сначала станет false, а затем true
Чтобы превратить тип данных в числовое можно использовать:
- Функцию Number('5')
- метод parseInt("5")
Что превратить тип данных в строку можно использовать:
- Функцию String(null)
- Или через метод Object.prototype.toString(43)
Разница заключается в том, что неявное преобразование происходит автоматически путем арифметических действий, а явное когда мы указываем тип специально через функции Number или ParseInt, функцию String или метод toString, Boolean или двойное логическое !!
console.log(Boolean("0")) // true
console.log(Number(" 123 ")) // 123
console.log(Number(true)) // 1
console.log(Number(false)) // 0
console.log(Number(' 123z ')) // NaNДоп.вопрос: Перечислите все ложные (falsy) значение?
Falsy - это следующие значение: "", 0, null, undefined, NaN, false. А все остальное уже true
Доп.вопрос: Что такое NaN?
NaN (not-a-number) - не является числом. Мы получаем его когда выполняем математическую операцию неправильно. Например, если мы infinity разделим на infinity, то оно нам даст NaN. Для того, чтобы проверить, что число не является числом использует функцию isNaN(). А его особенностью можно выделить то, что она не равна ничему даже самому себе как в строгом, так и в нестрогом сравнении.
Какие операторы есть в JavaScript?
Арифметические операторы: сложения; вычитания; умножения; делание; возведение в стене **; взятия от остатка %.
Операторы сравнения: > (больше); < (меньше); = (равно); != (не равно), == (нестрогое сравнения) и === (строгое сравнения)
Логические операторы:: || (или), && (и), ! (логическое не)
Доп.вопрос: Чем отличается строгое сравнения от нестрогого?
Нестрогое сравнивает только значения без приведения типов, а строгая сравнивает и значения и типы
Доп.вопрос: Расскажи про логические операторы и их способности?
К особенностям можно отнести приоритетность, то есть И будет выполнятся раньше Или, но если мы обернем в скобки то данная приоритетность уже не будет иметь разницы.
- || (Или) - ищет первое истинное значение и возвращает его. А если его не находит, то возвращает последнее значение. У него приоритетность - 5
- && (И) - ищет первое ложное значение и возвращает его. А если оба значения являются истинными, то возвращает последнее. Приоритетность - 6
- ! (Логическое не) - меняет значение на противоположное. Например если строку мы обернет в логическое !'str', то у нас false. Приоритетность - 15
Доп.вопрос: Что такое оператор нулевого слияния ??
Он возвращает значение правого операнда, если левый операнд содержит null или undefined, в противном случае возвращается значение левого операнда. Он похож на || (Или), так как он возвращает правый операнд если в левом хранится ложное значение, а не только null / undefined
Примеры:
null ?? 1 || 1
undefined ?? 1 || 1
11 ?? 1 || 11Расскажите про циклы в JavaScript?
Циклы нужны для того, чтобы повторить какое-то действие несколько раз. Существует несколько видов циклов:
- Классический цикл
for (let i = 0; i > str; i++) {...} - Цикл через
for in==>for (const name in obj) {...}служит для перебора объекта и возвращает нам ключи. Если нам необходимо получить значения, внутри цикла нам необходимо в квадратных скобках написать значения. А если мы решим использовать их в массиве, то получим индексы. - for ... of - служит для перебора массива и возвращает нам значения.
Доп.вопрос: Что такое выражения (expression) и инструкции (statement)
I. Выражение - это арифметическое действие. Например:+, -, *, /, %, >, =, ==, i++, --i, Math.random - случайное число.
II. Инструкция - это фрагмент кода, который выполняет определенное действие. К инструкциям относятся: if, if-else, while, for, for..in, for..of switch, for-in, объявления переменных
Доп.вопрос: Что такое switch/case и где он используется?
Switch + case - это по сути аналог if ... else, где выражение switch сравнивается с различными значениями case. Внутри каждого case используется break, чтобы выйти из конструкции и избежать выполнения следующих блоков. А также есть default, который означает что не одно из условий не выполнено
Если говорить про react, то используется он в reducer (redux). И например когда нам нужно именно точное сравнения
Доп.вопрос: Отличие while и do while
do ... while - должен выполнится хотя бы один раз и не важно верны ли условия или нет, в то время как while может и не выполнится если условия не подходят
while (условие) { // тело цикла }
do { // тело цикла } while (условие);
Какие ты знаешь методы у строк JavaScript?
.toUpperCase()- берет строку и пишет ее с большой буквы (преобразованное в верхний регистр)..toLowerCase()- берет строку и пишет ее с маленькой буквы (преобразованное в нижний регистр)..split()- делает из строки массив.trim()- удаляет пробельные символы с начало и конца строки.startsWith()проверяют начинается-ли строка с определенного символа который мы укажем внутри.endsWith()делает противоположное, то есть заканчивается строка c определенным символом.repeat()- повторяет строку указанное количество раз.includes()- проверяет, есть ли внутри строки указанная подстрока (часть текста). Возвращает true или false..replace()- находит в строке первое совпадение с шаблоном (или строкой) и заменяет его на указанную новую строку..slice()- вырезает часть строки и возвращает ее, не меняя оригинал. Можно указать с какого индекса начать и где закончить.
Доп.вопрос: Расскажи какие знаешь методы чисел (number) и математические (math)
.toString()- число преобразовывает в строку.parseInt()- берет строку и возвращает целое число.isNaN()- проверяет, является ли значения числа NaN.isFinite()- проверяет, является ли число конечным;
.min(1, 2, 3)- вернуть минимальное число.max(2, 3, 4)- вернуть максимальное число.random(1, 2, 3)- можно получить рандомное число.floor()- округляет в меньшую степень.ceil()- округляет в большую степень.pow(2, 3)- принимает два значения и возвращает возведенную степень(3, 3) // 27.abs()- возвращает абсолютное значение числа. Если это пустые кавычки или пустой массив, то это 0
Ну и другие по типу косинуса, синуса метода
Доп.вопрос: Расскажи какие знаешь методы массива (array)
.filter()
.map()
.forEach()
.sort()
.reduce()
.concat() - когда есть два разных массива и нам нужна их объединить
.isArray() => проверяет является ли значение массивом
.find() - вернёт первый найденный в массиве элемент, который подходит под условие.
.findIndex() - возвращает уже не найденный элемент, а индекс
Следующие 4 метода меняют исходных массив
.push() - добавляет элементы в конец массива и возвращает новую длину массива.
.pop() - удаляет из массива последний элемент и возвращает его значение.
.unshift() - добавляет элементы в начало массива и возвращают новую длину массива.
.shift() - удаляет из массива первый элемент и возвращает его значение.
Доп.вопрос: Что будет работать быстрее `pop`, `push` shift и unshift
Что будет работать быстрее? => Pop и push - так как их задача лишь добавить или удалить элемент в конце массива, а shift и unshift медленнее так как помимо удаление или добавления первого элемент они будут сдвигать массив вправо или влево.
Доп.вопрос: Что ты можешь рассказать о методах .splice(), .slice()
.splice() - меняет исходный массив, добавив либо удалив по индексу данные
.slice() - возвращает новый массив, содержащий какую-то определенную часть исходного массива. Например когда нам надо вернуть не весь массив, а только первые 2 элемента
Доп.вопрос: Какие методы мутируют и не мутирует исходный массив?
Мутирует - .sort, .reverse, .push. .pop, .shift, unshift, .splice
Не мутируют - map, filter, slice, concat,
Расскажите про объект?
Объект в JavaScript — это тип данных, который используется для хранения коллекций значений в виде пары ключ: значение. Ключи — это обычно строки (или символы), а значения могут быть любыми типами данных, включая другие объекты. И объекты никогда не равны друг другу, так как имеет ссылочный тип данных.
Доп.вопрос: какая разница между объектом и массивом
- У массивов есть методы тех, которых нет у объекта, также и наоборот
- Чтобы обратится к какому-то элементу в массиве мы должны использовать индекс от нуля. А у объекта обращение идет через точку
- Также у массива есть свойство length - делает подсчет всех элементов внутри массива.
Доп.вопрос: как мы можем определить наличие св-в в объекте
hasOwnProperty()- проверяет наличие свойств только в самом объектеin- проверяет наличие свойств как в самом объекте, так и в прототипах- Обратится к объекты напрямую с помощью индексовой нотации:
console.log(obj['prop1']); => foo
let value = {
prop1: "foo",
prop2: "bar",
};
console.log(obj.hasOwnProperty("prop1")) // True
console.log(obj.hasOwnProperty("prop3")) // False
console.log("prop1" in obj) // True
console.log("prop3" in obj) // False
console.log(obj["prop1"]) // foo
console.log(obj["prop3"]) // undefinedДоп.вопрос: В чем отличие методов объекта: key(), values(), entries(), fromEntries()
Object.keys()- возвращает массив ключейObject.values()- возвращает массив значенийObject.entries()- возвращает массив ключей и массив значенияObject.fromEntries()- у нас есть многомерный массив и с помощью данного метода мы можем преобразовать его в объект с ключом и значением
let user = {
name: "John",
age: 30,
}
Object.keys(user); // ["name", "age"]
Object.values(user); // ["John, 30]
Object.entries(user); // _0: (2) ['name', 'John']; _1: (2) ['age', 30]
let user = [
[0, 2],
[1, 3],
["vulgar", true],
]
console.log(Object.fromEntries(user)) // {0: 2, 1: 3, vulgar: true}Для чего нужен строгий режим в JavaScript?
Строгий режим помогает писать более безопасный код, и помогает находить потенциальные ошибки
- Например мы обратились к переменной, но самой переменной нету.
- Говорит о том, что нельзя дублировать параметры внутри функции -
function(a, a, b) - Например по умолчанию this ссылается на window, а при строгом режиме вернет undefined
Какие существуют типы всплывающих окон и типы ошибок в JavaScript?
Типы всплывающих окон:
alert - выводить информацию во всплывающем окне;
confirm - спрашивать соглашение во всплывающем окне; подтвердить по ОК или Отмену
prompt - всплывающем окно, где просят написать что-то в инпут поле
Типы ошибок:
SyntaxError - синтаксическая ошибка возникает когда мы написали неправильно какое-то слово: return
ReferenceError - возникает когда js не может найти какую-то ссылку в которой мы пытаемся получить доступ. Например хотим определенную переменную найти а его нет
TypeError - ошибка в типе - например у нас есть переменная, а мы к нему обращаемся через объект или пытаемся вызвать его.
Разница между переменными: var, let и const?
Letиconstпоявились в ES6, аvarбыл еще до него;Letиconstимеют блочную область видимости, а var - глобальную (или локальную);Letмы можем присвоить новое значение, однако не можем создать переменную с тем же именем, уconstмы не можем присвоить новое значение. Уvarмы можем как присвоить новое значение, так и повторно объявить. Раньше чтобы решить проблему области видимости уvarлюди оборачивали в так называемые анонимные самовызывающиеся функции;- Есть такое понятие как временная мертва зона (temporal dead zone), что означает мы не можем вызвать переменная до его инициализации, и она появилась с let и const. Если мы попытаемся вызвать их то получаем ошибку, однако в случае с var у нас просто выведется undefined, это связано с всплытием.
- Var сплывает, а let и const нет
Доп.вопрос: А что если мы не объявили переменную?
Необъявленная переменная - это когда мы написали какое-то значение a = 20 без переменных var, let либо const. Область видимости у необъявленных переменных - глобальная, что означает, что они доступны из любого места кода, что не очень хорошая практика как и var. Если мы будем использовать строгий режим, то получим ошибку ReferenceError, а в нестрогом undefined
Доп.вопрос: А какие есть правила задавания имен переменных и функций
Если мы говорим задание имен переменных, то
-
Они должны содержать буквы на латинице, он должен отражать смысл того, что он хранит:
let age = 20; -
Цифр:
let user2 = 'Antony'; -
Символы доллара:
let $user = 'Alice'; -
Нижнего подчеркивания:
let _user = 'Pete';
Если мы говорим то, что как не стоит начинать, то - первый символ не должен быть цифрой: let 10user = 'Nick';
Имя функции должно понятно и четко отражать что она делает и что возвращает. Функция - это действия по этому её имя
обычно является глаголом: function checkValue() {}
Расскажите про область видимости (scope)?
Глобальная область видимости - это когда мы объявляем переменную внутри самого файла js-файла, Она доступна уже из любого места в коде.
Функциональная область видимости - переменные объявленные внутри функций
Блочная область видимости - это когда переменная доступна только внутри блока, за пределами блока она не доступна.
Разница между function declaration и function expression?
Выделяют два способа объявлении функции:
- Через ключевое слово: function =>
function multyple() {...} - Через переменную
let multiply = function () {...}
Ключевое отличие: Function declaration можно вызывать до объявления благодаря всплытию (hoisting), а function expression — нет.
Подробнее:
Отличие заключается в том, что к function declaration можно вызвать до того как объявить. Так как JS собирает все строчки где объявляется function, а также через Hoisting (поднимает) их самый вверх, что позволяет нам сначала вызвать их, а потом объявить. Еще наверное стоит отметить, что если мы объявим function expression через переменную var, то и она будет всплывать
Доп.вопрос: Как передаются параметры в функцию: по ссылке или по значению?
Когда мы передаем значения в функцию, то создается копия этого значение, в то время как объект передает ссылку на участок памяти где был вызван объект
var n = 1;
function f(n) {
n = 3;
}
f(n)
console.log(n) // 1var obj = { a: 1 };
function f1(o) {
o.a = 5;
}
f1(obj)
console.log(obj) // { a: 5 }
// Во второй случае передается уже ссылка на объект. По этому ответ 5Доп.вопрос: Разница между параметром и аргументом функции?
Когда мы пишем функцию и внутри обычных скобок указываем a, b: function value (a, b) {...}, то это параметры.
После того как мы передали параметры мы пишем код например return a + b. После вызываем этой функцию через запятую,
так вот значения, которые передаются при вызове функции называются аргументами: foo (5, 7).
Что такое всплытие (Hoisting)?
Всплытие — это механизм в JavaScript, при котором объявления переменных (var) и функций (function declaration) "поднимаются" в начало своей области видимости, что позволяет использовать их до фактического объявления в коде.
Что такое замыкание (Closure)?
Замыкание - это способность функции помнить переменные вокруг себя и иметь доступ к этим переменным, где бы и когда бы её ни вызвали.
function outer() {
const outerVar = 'Я из внешней функции!';
// Эта внутренняя функция и есть замыкание
function inner() {
console.log(outerVar); // Используем переменную из внешней области видимости
}
return inner; // Возвращаем функцию, а не её результат
}
const closureFunction = outer();
closureFunction();Разница между обычными функциями и стрелочными?
- Синтаксис;
- Обычные функции всплывают, а стрелочные нет, если конечно они не объявлены через var;
- В обычных функция this - динамический (в зависимости от того, где мы его вызываем, на то он и будет ссылаться), а у стрелочных — лексический (определяется при объявлении).
- В обычных функция можно использовать arguments, а у стрелочных нет аргумента -
вместо этого можно использовать spread-оператор - Обычные функции могут быть вызваны с конструктором new, а стрелочные нет. Если мы попытаемся использовать стрелочную функцию как конструктор, то получим ошибку
Что такое this (контекст) и для чего нужен .call(), .apply() и bind()?
This - ключевое слово, которое указывает на контекст выполнения функции и он является динамическим. В зависимости от того, где мы его вызываем, на то он и будет ссылаться. Например: если вызовем глобально без use strict. то получим window, а если с ним то ошибку, если в терминале,
Методы .call(), .apply() и bind() используются для управления значением this, отличие в том, что:
.call() и .apply() - вызываются сразу, а .bind() - привязывает к контексту и вызывается позже, и если .bind у нас много, то сработает только первый.
Также стоит отметить, что аргументы у .call(obj, '', '') указываются через запятую, а у .apply(obj, ['', '']) в виде массива
const person1 = { name: 'Алиса', age: 25 };
const person2 = { name: 'Боб', age: 30 };
function introduce(greeting, punctuation) {
console.log(`${greeting}, меня зовут ${this.name}${punctuation}`);
}
introduce.call(person1, 'Привет', '!'); // "Привет, меня зовут Алиса!"
introduce.apply(person1, ['Привет', '!']); // "Привет, меня зовут Алиса!"
introduce.call(person2, 'Здравствуйте', '.'); // "Здравствуйте, меня зовут Боб."
introduce.apply(person2, ['Добрый день', '...']); // "Добрый день, меня зовут Боб..."
const introduceAlice = introduce.bind(person1);
const introduceBob = introduce.bind(person2);
// Теперь можем вызывать их когда угодно
introduceAlice('Хай', '!'); // "Хай, меня зовут Алиса!"
introduceBob('Привет', '.'); // "Привет, меня зовут Боб."Задача №1
console.log(this)Ответ: Если говорим про браузер, то в строгом и нестрогом режиме покажет object window. А если в терминале, то это object global
Задача №2
function show() {
console.log(this)
}
show();
const showArrow = () => {
console.log(this);
}
showArrow();Если говорить про браузер:
- В нестрогом режиме оба покажут Window
- В строгом режиме show будет undefined, а стрелочная функция покажется Window так как у него нет своего this и он будет брать из лексического окружение, в данном случае глобально
- Если говорить про терминал, то в будет объект, а в строгом режиме будет с show undefined, а у стрелочной функции пусть объект
Задача №3
const obj = {
name: 'Test',
showName() {
console.log(this.name)
},
showThis_01() {
console.log(this);
},
inner: {
showThis_02() {
console.log(this);
}
}
};
obj.showName(); // 1
obj.showThis_01(); // 2
obj.inner.showThis_02(); // 3В showName выведется "Test", так как он ссылается на имя В showThis_01 => this будет ссылаться на весь объект В obj.inner.showThis_02() выведется функцию showThis_02 {...} так как this ссылается на вложенный метод
Задача №4
const obj = {
a: 1,
say() {
return function() {
console.log(this.a)
}
}
}Контекст теряется когда мы возвращаем функцию и туда передается undefined. Исправить можно это с помощью стрелочной функции, который запоминает значение
Задача №5 - Что будет выведено
let obj1 = {
name: "User 1",
getName() {
console.log(`name is: ${this.name}`);
},
};
let obj2 = {
name: "User 2",
getName() {
console.log(`name is: ${this.name}`);
},
};
let fn = obj1.getName.bind(obj2).bind(obj1);
fn();Выведется name is User2 - сработает только первый bind и последующие будут игнорироватся
Задача №6 - Что будет выведено и как это исправить?
let obj = {
name: "David",
getName() {
console.log(`name is: ${this.name}`);
},
};
let fn = obj.getName;
fn();Вызывается обычная функция, у него нет привязки к this, так как это не метод и вернет пустую строку
Исправить можно:
- Переписав на стрелочную функцию
- Забайндить => obj.getName.bind(obj);
- Вызывать напрямую без let fn
Задача №7 - Объясните, что происходит в данном коде и какой будет вывод в консоль при его выполнении.
const object = {
firstName: "Bill",
lastName: "Ivanov",
sayLastName: () => {
console.log(this.lastName);
},
sayName() {
console.log(this.firstName);
},
};
object.sayName(); // 1.
object.sayLastName(); // 2.
var b = object.sayName;
b(); // 3.
object.sayName.bind({ firstName: "Cash" })(); // 4.
object.sayLastName.bind({ firstName: "Arrow" })(); // 5.
object.sayName.bind({ firstName: "Name1" }).bind({ firstName: "Name2" })(); // 6Ответ:
- Bill, так как this ссылается на Bill
- Undefined, this берется из глобального лексического окружения по этому undefined
- Undefined, функция вызывается без контекста
- 'Cash', привязывает новый контекст
- Undefined, стрелочная функция НЕ имеет своего this, bind не может изменить ее контекст, this берется из внешней области
- Name1, так как сработает только первый bind последующие будут игнорироваться
Задача №8 - Что выведется в консоль
'use strict'
var obj = {
i: 10,
b: () => console.log(this.i, this),
c: function() {
console.log(this.i, this)
}
}
obj.b()
obj.c()undefined window 10 сам объект
Задача №9 - Что будет выведено
function foo() {
const x = 10;
return {
x: 20,
// x: 30
bar() {
console.log(this.x);
},
baz: () => {
console.log(this.x);
},
};
}
const obj1 = foo();
obj1.bar(); // 1
obj1.baz(); // 2
const obj2 = foo.call({ x: 30 });
let y = obj2.bar;
let x = obj2.baz;
y(); // 3
x(); // 4
obj2.bar(); // 5
obj2.baz(); // 6Объяснения
- 20
- Undefined, так как this лексический и он будет ссылатся на window
- Undefined, обычная функция
- 30, стрелочная берет этот this
- 20 - обычный метод берется число 20
- 30 - из-за call стрелочная функция все еще 30
Задача № 10
let baz = 0;
let foo = {
bar1: function() {
return this.baz;
},
bar2: () => this.baz,
baz: 1
};
let fooCopy = {
bar1: foo.bar1,
bar2: foo.bar2,
baz: 1,
}
let bazzz = foo.bar1;
console.log(fooCopy.bar1())
console.log(fooCopy.bar2())
console.log(bazzz)1 undefined undefined
Задача № 11
function Person(name) {
this.name = name;
}
const juan = new Person("Juan");
Person.prototype = {
getName: function () {
return this.name;
},
};
const pedro = new Person("Pedro");
console.log(pedro.getName());
console.log(juan.getName());"Pedro" Ошибка: juan.getName is not a function
Что такое чистая функция? (Pure Function)
Чистая функция - это та функция, у которой нет побочных эффектов. К побочным эффектом относится: Запросы на сервер, Изменения входных параметров, Обращение к дому (query selector), если говорим про JS.
А также всегда возвращает один и тот же результат для одних и тех же аргументов.
Плюсы чистых функций:
- Уменьшает кол-во багов (так как он максимально низко влияет на остальную систему. Если я знаю, что у меня есть баг в функции, то он внутри него)
- Легче тестировать
- Легче понимать, поскольку все что она делает заключено внутри нее и не нужно никуда бегать.
Что такое функция генератор?
Генераторы — это функции, которые могут приостанавливать своё выполнение и возвращает значение через yield и возобновлять его позже через next().
У next кстати два состояние value и done, если он не конечный, то done: false, а если завершен то done: true
function* generatorFunction() {
yield 'Первое значение';
yield 'Второе значение';
return 'Финал';
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 'Первое значение', done: false }
console.log(gen.next()); // { value: 'Второе значение', done: false }
console.log(gen.next()); // { value: 'Финал', done: true }* Разница между синхронными и асинхронными функциями?
Синхронные функции являются блокирующими, а асинхронные нет. Когда интерпретатор натыкается на синхронную функцию, он блокирует дальнейшее выполнения операции прежде чем данная функция будет выполнения. По этому набор таких функций выполняется последовательно - одна за другой. Асинхронные функции наоборот не блокирует дальнейшие выполнения скрипта. По этой причине различные тяжелые операции по типу запроса данных делают асинхронными. Обычно такие функции в качестве аргумента принимают callback - это еще одна функции, которая выполнится как только будет выполнено асинхронная функция и которая сможет обработать полученный результат
* Типы функций по способности принимать другие функции?
В JS можно выделить 3 основные типов функций в зависимости от принимаемых данных:
- Функция первого класса (first-class functions) – это функция, которая не принимает другую функцию в качестве аргумента и не возвращает функцию как значения
const firstOrder = () => console.log( “Hello”)
- Функции высшего порядка (HOF) – это функция, которая принимает другую функцию в качестве аргумента или возвращает функцию как значение
const higherOrder = firstOrderReturn => firstOrderReturn()
- Унарная функция – это функция, которая принимает только 1 аргумент, который не является функцией.
const unaryFunction = (a) => console.log(${a} + world!)
* Что такое мемоизация? Реализуйте базовую логику функции для мемоизации?
Это прием создании функции способность запомнить ранее вычисленное значение, а также результат. В результате при повторном вызове функции с одинаковыми аргументами она не будет выполнена, а результат работы вернется из кеша.
В программировании мемоизация — это метод оптимизации , который делает приложения более эффективными и, следовательно, более быстрыми. Он делает это, сохраняя результаты вычислений в кеше и извлекая ту же информацию из кеша в следующий раз, когда она потребуется, вместо того, чтобы вычислять ее снова.
* Что такое функции высшего порядка (Higher Order Functions)?
HOF - обычная функция, которая принимает в качестве аргумента другую функцию, добавляет в эту функцию так скажем новый функционал и возвращает его - это map, filter, reduce
Что такое callback-функцию?
Callback — это функция, которая передаётся в другую функцию в качестве аргумента. Это один из способов работы с асинхронным кодом. Однако существует проблема, называемая Callback hell («ад колбэков»), когда внутри одного колбэка находится другой колбэк, внутри него — ещё один, и так далее. Такой код становится очень сложно читать, тестировать и поддерживать. Поэтому в ES6 появились Promise (промисы), а в ES8 — async/await
Что такое Promise и какие у него есть методы?
Promise представляет из себя специальный объект и у него есть три состояния: pending - ожидание, fulfilled - завершился успешно, rejected - выполнился с ошибкой.
У promise есть следующие методы
- Метод
.all()- дожидается выполнения ВСЕХ promises, если успешно вернет массив, если нет, то вернет последний promise с ошибкой .allSettled()- дожидается выполнения ВСЕХ promise, и не важно выполнятся они успешно или нет он вернет массив полученных значение (ответов), в котором будет два поля - это статус и значение, если успешно, а если не успешно то причина reason.any()- дожидается выполнения ПЕРВОГО УСПЕШНОГО promise и возвращает результат, если не находит возвращает ошибки внутри массива.race()дожидается выполнения ПЕРВОГО promise не важно успешно он или нет, и возвращает результат.
Например есть promise и мы вызываем какую-то функцию которая возвращает promise. Мы на него подписались через .then, .catch и т.д. Теперь вопрос а может ли быть ситуация когда promise никогда не закончится не then, не catch не вызовутся? Нам нужно чтобы оно было бесконечное как это сделать
const neverEndingPromise = new Promise((resolve, reject) => {
// ничего не делаем
});
Есть ли у promise какой-то функционал, что если через 5 секунд он ничего не сделал, то как принудительно зарезолвились или заречеджектились promise
Promise.race c SetTimeOut
function withTimeout(promise, timeout) {
return Promise.race([
promise,
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout exceeded')), timeout)
)
]);
}
// Использование
const somePromise = new Promise((resolve) => {
// Симуляция долгой операции
setTimeout(() => resolve('Done!'), 10000); // завершится через 10 секунд
});
withTimeout(somePromise, 5000) // Таймаут 5 секунд
.then(result => console.log(result))
.catch(error => console.error(error.message));
Что такое async/await? И что у него общего у promise
Async является еще одним способом написание асинхронного кода, который всегда возвращает promise, await добавляется в тело функции и ждет выполнения promise.
Если какой-то из await не выполнится, то дальше он не пойдет и поместится в catch, а это обработчиком ошибок
async function getMainActorProfileFromMovie(id) {
try {
const movieResponse = await fetch(`https://swapi.dev/api/films/${id}/`);
const movie = await movieResponse.json();
return characterResponse.json();
} catch (err) {
console.error('Произошла ошибка!', err);
}
}Что такое Eventloop (цикл событий) и как он работает?
Eventloop - это бесконечный цикл, который решает проблему однопоточности. У него есть callstack (стек вызовов), куда постоянно попадает задачи, он их выполняет и ждет снова поступления новых задачи. Задачи в свою очередь делятся на микро и макро-таски. У микро-тасок приоритетность больше и они будут выполняться раньше чем макро-таски. К микротаскам можно отнести then, catch, finally у промисов, queueMicrotask, MutationObserver, async await а к макро таском setTimeOut, setTimeInterval, событияЗадачи по evenloop и вывода консоль
Если все micro-task выполнятся а дальше пойдут macro-task внутри которого есть micro-task , что вызовется микро или макро
Сначала выполнится внутри micro-task , а затем уже macro-task
Каков будет ответ
new Promise((resolve, reject) => {
resolve(1);
resolve(2);
reject('error')
}).then(
(value) => console.log(value),
(error) => console.log('error')
)Промис вызовется один раз и ответ будет зарезволенный 1, а последующие будут игнорировать, по этому и ответ 1
Каков будет ответ
Promise.reject('a')
.catch((p) => p + 'b')
.catch((p) => p + 'c')
.then((p) => p + 'd')
.then((p) => console.log(p))
console.log('f')В начале получаем зареджектный а, потом мы ловим catch и будет 'ab', следующий catch пропуск так как мы уже обработали ошибку, затем идем в then и выводим 'abd'
Опиши подробно последовательность ответа
Promise.resolve(1)
.then((x) => x + 1)
.then((x) => { throw x } )
.then((x) => console.log(x))
.catch((err) => console.log(err))
.then(x => Promise.resolve(x))
.catch((err) => console.log(err))
.then((x) => console.log(x))Есть зарезвлоенный промис 1, мы идем к then получаем 2, затем выбрасываем ошибку после чего следующий then пропускаем и в блоке catch на пятой строчке мы как раз выводим и нашу двойку потому что мы ранее выбрасили двойку. После блока catch ошибка у нас считается обработанной по этому мы идем выполнения then. В следующем then у нас в качестве x ничего не передается и значит результат равен undefined. Блок catch пропускаем так как ошибок у нас нет и на последней строчке мы этот undefined выводим в консоль
Level №1 - Простой порядок
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'););
console.log('4');Ответ: 1432
Решение: 1 и 4 попадут в стек сразу выполнятся так как они синхронные, 3 попадает в микротаски и выполнится сразу, а 2 идет к макротаскам и он выполнится последним
Level №2 - Микрозадачи vs макрозадачи
setTimeout(() => console.log('timeout'));
Promise.resolve().then(() => console.log('promise'));
queueMicrotask(() => console.log('microtask'));
console.log('code');Ответ: code → promise → microtask → timeout
Решение: code выполнится сразу, затем идет две микрозадачи в очередь - promise и microtask, и выполнятся в начале все они, а затем уже timeout который в макрозадачи
Level №3
Promise.resolve()
.then(() => {
console.log('promise1');
Promise.resolve()
.then(() => console.log('promise2'));
})
.then(() => console.log('promise3'));
console.log('code');Ответ: code → promise1 → promise2 → promise3
Вначале выполнится code, затем в callstack будут записан then и внутри него создастя еще одна микрозадача с promise2, пока все микрозадачи первого зена не завершится он не перейлет к следующему then с промис3
все внутренности первого зена включая промиса, а затем уже второй then отработает
Level №4
console.log(1);
setTimeout(() => console.log(2));
Promise.resolve().then(() => console.log(3));
Promise.resolve().then(() => setTimeout(() => console.log(4)));
Promise.resolve(console.log(5)).then(() => console.log(6));
setTimeout(() => console.log(7));
console.log(8); Ответ: 1 -> 5 -> 8 -> 3 -> 6 -> 2 -> 7 -> 4
Решение: в начале выполнится 1 в console.log, затем 5 хоть она и в промисе, но аргумент из Promise.resolve() вычисляется синхронно, и чтобы быть в микрозадачи нужно быть в .then, .catch, затем синхронный код 8, а теперь разбираем все микрозадачи это 3 и 6, 4 уходит в макрозадачу. И у нас остается 3 макрозадачи - setTimeout 2, 7, 4. А в самом конце 4, потому что он попал в очередь макротаск после того как там уже было 2 и 7 и он добавился в конец
Level №5
setTimeout(function timeout() {
console.log("Таймаут");
}, 0);
let p = new Promise(function (resolve, reject) {
console.log("Создание промиса");
resolve();
});
p.then(function () {
console.log("Обработка промиса");
});
console.log("Конец скрипта");Ответ: Конец скрипта -> Создание промиса -> Обработка промиса -> Таймаут
Решение => у нас then., .catch, .finally - ассинхронны, а простой вызов промиса синхронный по этому в начале у нас выполнится синхронные операции - это создание промиса, конец скрипта, обработка промиса (микротаска) и Таймаут (макротаска)
Level №6
const promise = new Promise((resolve) => {
console.log(1);
setTimeout(() => {
console.log("timerStart");
resolve("success");
console.log("timerEnd");
});
console.log(2);
});
promise.then((res) => console.log(res));
console.log(4);Ответ: 1 -> 2 -> 4 -> timerStart -> timerEnd -> success
Решение:
- Сначала выполняются все синхронные операции (console.log(1), console.log(2), console.log(4)).
- Затем срабатывает setTimeout, выполняя console.log("timerStart"), затем resolve("success"), затем console.log("timerEnd").
- После завершения макрозадачи setTimeout, обрабатывается микрозадача promise.then(), которая выводит "success".
Level №7
console.log(1); // вывод синхронный
setTimeout(function timeout() {
console.log("Таймаут");
}, 0);
new Promise(function (resolve, reject) {
console.log("Promise"); // вывод синхронный
setTimeout(() => {
console.log(777);
resolve();
}, 0);
})
.then(() => console.log("then1"))
.then(() => console.log("then2"));
console.log(4); // вывод синхронный
setTimeout(() => {
console.log("timeOut2");
}, 0);Решение:
- В начале выполняем все синхронны операции это 1, затем settimeout идет в макротаски. Внутри конструктора есть промис это синхронная операция Promise вывелся, и следующий setTimeout идет к макротаском, then1 и then2 пропускается так в начале должен выполнится setTimeout в макротаске. Выводим затем 4 он тоже синхронный и у нас остается последняя макротаска - timeout2. Теперь разберем макротаски - выводим первый таймаут, затем внутри сработывает второй таймаут выводится 777 и промис резолвится и срабатывают then1 и then2 в конце срабатывает последний макротаск timeout2
Level №8
setTimeout(console.log(1));
new Promise(function (resolve, reject) {
resolve();
})
.then(() => console.log(2))
.then(() => console.log(3))
.catch(() => console.log("err"))
.then(() => setTimeout(() => console.log(4)));
console.log(5);Ответ: 1 => 5 => 2 => 3 => 4
Решение: setTimeout(console.log(1)) получает результат выполнения сразу, а это означает что он синхронный, дальше промис зарезовленный и мы получаем 2, 3, catch пропускаем и получаем 4 который берем из макротаски
Level №9
console.log("A");
const p = new Promise((resolve) => {
resolve("");
console.log("B");
});
p.then(() => {
p.then(() => console.log("C"));
console.log("D");
});
setTimeout(() => {
console.log("E");
}, 0);
p.then(() => console.log("F"));Ответ: А => B => D => F => С => E
Решение => A (синхронный код), B (синхронный код), первый then (внутри него: выводит D и создает новую задачу C в конец очереди), затем выполняется F (который уже был в очереди перед C), затем выполняется C (добавленный позже), затем макрозадача E.
Level №10
setInterval(() => console.log(1), 1)
setTimeout(() => console.log(2), 1)
console.log(3);
Promise.resolve().then(() => console.log(4));
const promiseTest = new Promise(() => {
console.log(5)
})
setTimeout(() => console.log(6), 0)
console.log(7)
promiseTest.then(() => console.log(8))Ответ: 3 => 5 => 7 => 4 => 6 => 2 => 1111111
Решение:
- => 357 - синхронные операции
- => 4 - микротаска, 8 пропускаем так как нет resolve
- => 6 и 2 выполняются по очереди в микросекундах
- => setInterval до самого конца идет 1 1 1 1
Level №11
setTimeout(() => console.log("setTimeout 1"), 0);
new Promise((resolve, reject) => {
console.log("Promise 1");
resolve();
console.log("Promise 2");
}).then(() => console.log("Promise 3"));
Promise.resolve().then(() => setTimeout(() => console.log("setTimeout 2"), 0));
Promise.resolve().then(() => console.log("Promise 4"));
setTimeout(() => console.log("setTimeout 3"), 0);
console.log("final");Ответ: Promise1, Promise2, final, Promise3, Promise4, setTimeout1, setTimeout2, setTimeout3
Level №12
console.log(1)
setTimeout(() => {
console.log(2)
})
Promise.resolve().then(() => {
console.log(3)
})
console.log(4);
setTimeout(() => {
console.log(5)
}, 0)
console.log(6);
const fool = () => {
console.log('foo1');
return Promise.resolve().then(fool)
}
fool();Ответ: 146 => foo1 => 3 => fool бесконечно и микрозадача никогда пустой не станет
Level №13
async function f() {
console.log(1);
const promise = new Promise((resolve) => {
console.log(2);
setTimeout(() => {
console.log(3);
resolve('готово!')
console.log(4)
})
})
console.log(5);
const result = await promise;
console.log(6)
console.log(result)
return 'Result'
}
f();
console.log(7);Ответ: 1 => 2 => 5 => 6 => 7 => 3 => 4 => ГОТОВО
Объяснения, в начале у нас срабатывает до await код - это 1 2 5 потом выходит из функции и срабатывает 7 заходит обратно и мы должны выполнить все операции промиса так 3 4 6 'готово'
Level №14
function checkOrder() {
console.log('1');
async function asyncFn() {
console.log('2');
await Promise.resolve(null);
console.log('3')
}
asyncFn();
new Promise((resolve) => {
setTimeout(() => {
resolve();
console.log('4')
}, 0);
console.log('5')
}).then(() => console.log('6'))
console.log('7')
}
console.log('8');
checkOrder();
console.log('9')--- На
Ответ: 8 => 1 => 2 => 5 => 7 => 9 => 3 => 4 => 6
Level №15
console.log('1')
setTimeout(() => console.log('2'), 0)
async function asyncFunc() {
console.log('3')
await new Promise((resolve) => {
console.log('4');
setTimeout(() => {
console.log('5');
resolve()
}, 0)
})
console.log('6')
Promise.resolve()
.then(() => console.log('7'))
.then(() => console.log('8'))
}
asyncFunc();
console.log('9')Ответ: 1 => 3 => 4 => 9 => 2 => 5 => 6 => 7 => 8
Level №15
setTimeout(() => console.log('timeout'));
Promise.resolve().then(() => Promise.reject('reject').catch(console.log));
window.requestIdleCallback(() => console.log('requestIdleCallback'));
window.requestAnimationFrame(() => console.log('requestAnimationFrame'));
console.log('code')Ответ: code (синхронный код) => reject (микротаска) => requestAnimationFrame(сработает перед полной загрузкой страницы хоть и тоже макротаска) => timeout => requestIdleCallback(уже после завершение страниц)
Какие типы таймеров есть в JavaScript?
В JS есть два основных типа таймеров:
setTimeout(...)- позволяет вызвать переданную функцию один раз через определенное времяsetInterval(...)- позволяет вызвать переданную функцию много раз через определенный интервал времени. Чтобы отменитьsetIntervalмы можем использовать тип:clearInterval()и внутрь передаем переменную, где использовалиsetInterval.
Что такое прототип в JS? И как работает цепочка прототипов
Прототип - это специальная ссылка на другой объект, он содержит свойства и методы, к которым объект может обратиться через прототипное наследование. Когда мы обращаемся к свойству объекта, JavaScript сначала ищет его в самом объекте. Если не находит — переходит по ссылке в прототип и ищет там. Затем — в прототипе прототипа, и так далее, пока цепочка не закончится на null (это значит, что свойство не найдено).
В коде мы можем получить к ней доступ через геттер/сеттер Object.getPrototypeOf(obj) / Object.setPrototypeOf(obj, proto) или через устаревшее свойство proto.
- Что произойдет если запрашиваемая св-в не найдено в объекте? - Вернет undefined
В чём разница между __proto__ и prototype?
Prototype - это свойство функции-конструктора объявленный через new, а proto - свойство любого объекта, который ссылается на его прототип (на объект prototype функции-конструктора).
Что такое DOM (document object model) ?
DOM (Document Object Model) — это специальная древовидная структура, которая позволяет управлять HTML-разметкой из JavaScript-кода. Управление обычно состоит из добавления и удаления элементов, изменения их стилей и содержимого.
Доп.вопрос: какие ты знаешь методы поиска элементов в DOM?
document.getElementById('id') - поиск по Id, если он есть;
querySelector('class') - возвращает первые найденный элемент по классу;
querySelectorAll('class') - возвращает все элементы, который подходят классу
Есть также другие способы (они более старые)
elem.getElementsByTagName(tag) поиск по тегу;
elem.getElementsByClassName(className) поиск по имени класса;
Что такое распространение события (Event Propagation)?
Дополнить ....
Что такое делегирование событий (Event Delegation)?
Дополнить ....
Что такое всплытие и погружение?
Всплытие событие
Доп.вопрос: что делает event.preventDefault()
Доп.вопрос: что делает event.stopPropagation()
...
Доп.вопрос: что делает event.stopImmediatePropagation()
...
Разница между e.preventDefault() и e.stopPropagation() и e.stopImmediatePropagation()?
Разница между event.target и event.currentTarget?
Переделать ....
event.target - элемент на котором произошло событие
event.currentTarget - элемент на котором висит обработчик.
Виды (обработчик) событий в JavaScript?
Есть несколько видов событий:
-
Событие по мыши -
click(клик мышки),dblclick(двойной клик),mouseover(навели на элемент), mouseout (увели от элемента мышь) -
События клавиатуру -
keydownиkeyup- когда клавиша нажата и опущена -
События формы -
change(изменения значения),focus,blur,submit
Доп.вопрос: Для чего используется метод .focus() и blur()?
Например когда у нас загрузилась страница, то с помощью метода focus() мы можем сразу же попросить пользователя ввести необходимые данные. Ему не нужна будет кликать на определенный input. Метод focus() устанавливает focus на элемент
.blur() - снимает фокус с элемента. Например когда мы отправили форму либо кликнули за пределами input поля
Доп.вопрос: Как называется события которое свидетельствует о том, что наш дом полностью загружен?
domContentLoaded
Для чего используется свойство window.navigator?
Необходим для получения информации о браузере и его среде исполнения
navigator.userAgent - информацию о браузере и операционной системе
navigator.language – основной язык браузера (например, "ru-RU").
navigator.languages – массив предпочтительных языков.
navigator.geolocation – доступ к геолокации.
navigator.mediaDevices – доступ к камере и микрофону.
navigator.bluetooth, navigator.usb – доступ к устройствам Bluetooth и USB.
Разница между методами Light dom и shadow dom?
Дополнить ....
Какие ещё способы назначить обработчик, кроме addEventListener?
-
Через onclick когда инлайного мы пишем в HTML коде.
-
Либо пишем квериселектор, а потом вызываем onclick и вешаем его на кнопку
Что такое SOLID и расшифруйте его?
-
S
(single responsibility principle)- принцип единственной ответственный. Один класс, компонент должен выполнять лишь 1 задачу (ответственность) -
O
(open-closed principle)- принцип открытости и закрытости. Код написанные на классах, компонентов должен быть открыт для расширения, но закрыт для изменения.
Например - вместо того чтобы внутри одного класса сделать куча условий на if, мы создаем один абстрактный класс для скидок и от него наследуемся создавая уже конкретные скидки по типу - Ежедневных скидок, в честь 8 марта и прочее и прочее.
-
L
(liskov substitution principle)- принцип подставки Барбары Лисков. Наследуемый класс, компонент должен расширять, а не заменять поведение базового (родительского) класса -
I
(interface segregation principle)- принцип разделения интерфейса. Принцип гласит, что не стоит хранить все в одном месте и необходимо разбивать код на более мелкие компоненты (классы/интерфейсы) связанные по логике -
D
(dependency inversion)- принцип инверсии зависимостей
---.
D => Dependency inversion (принцип инверсии зависимостей) => модули высокого уровня не должны зависеть от модулей более низкого уровня, все они должны зависеть от абстракций, а они в свою очередь не должны зависеть от деталей, а детали как раз должны зависеть от абстракции.
У нас есть завод, внутри завода есть станки, работники, электричество = они между собой связаны, в свою очередь станки также могут иметь детали: скажем наручник №1, крутилка №007. Представим себе что одна из деталей сломалось, мы меняем эту деталь в станке и оказывается, что логика работы станка меняется. Наши работники с этим станком теперь работать не могут, или для другой детали нужна будет более мощное электричество и здесь как раз происходит принцип инверсии зависимостей. У нас модули высокого уровня зависят от модулей низкого уровня. Чтобы этого избежать - можно исп так называемый трансформатор (некая абстракция), который сам подберет напряжения
Что такое ООП?
Полиморфизм - способность функции работать с различными типами данных. Например есть функция, которые может принимать разные типы данных: string и number, но функция одна.
TypeScript
Что такое TypeScript и какие преимущество и недостатки у него?
TypeScript - строго-типизированным язык от Microsoft, который потом компилируется в JS.
К преимуществом можно отнести:
- Любой код, который будем писать на TypeScript, он будет валиден для JavaScript
- Он делает код более читаемым
- Мы можем явно указывать типы для переменных; функций(что ожидаем на вход и выход); для классов и прочее;
- К преимуществом можно также отнести, что TS показывает ошибки во время разработке. Например когда указали неправильный тип
К недостатком:
- Все таки нужна компиляция в JavaScript
- Приходится писать больше кода для описание типов и интерфейсов
- Бывают когда типы разрастаются, и сложно читать их
Будут ли какие-то отличия для типизации, если поля будут идти не в том порядке, вак у нас описано в типе?
Для TypeScript нет
Чем отличается type/interface?
-
Синтаксис
-
В интерфейсах наследование есть, а в типах нет
-
Если мы хотим взять какой-то примитивный тип у type, то внутри interface мы можем обратится к типу объявленный через type
-
Если у нас есть два типа, то мы можем объединить через | (пересечение типов), у интерфейса такой функции нету.
-
Если мы напишем два интерфейса с одинаковыми именами, то они объединяться в то время как типы выдаст ошибку
Перечислите основные типы TypeScript?
Помимо основных 3 примитивных типов - string, number, boolean. Есть также
-
Any- говорим TS, что тип может быть любым. Словно мы пишем на голом JS, он небезопасный, так как в процессе работы с данным типом к нему присвоится любой другой тип -
unknown- похож на тип any, но он более безопасный, мы в начале проверяем через typeof какой тип мы ожидаем, а уже внутри делаем условия. П.С. Тип может быть любой -
void- означает, что у функция нет возвращаемого значения. -
never- означает, что функция никогда не завершится. Используем когда хотим выбросить ошибку и с бесконечным циклом
Чем отличается union - `I` и intersection-(&) типы
Если говорить про union тип - I, то мы говорим, что тип может быть одним из перечисляемых. Например либо строка либо число, но если данного типа нет, то выбрасывается ошибка ТС
type StringOrNumber = string | number;
let value: StringOrNumber;
value = "Привет";
value = 42;
value = true; // Ошибка: boolean не входит в string | numberВ то время у Intersection - & когда все поля в интерфейсах должны быть обязательными к заполнению. Если пропустим какой-то тип, то выбросит ошибку, что данное поля нет например в объекте
interface Person { name: string; }
interface Employee { company: string; }
type EmployeePerson = Person & Employee;
const john: EmployeePerson = { name: "John", company: "Tech Corp" };
// ОШИБКА - отсутствует поле 'company'
const invalidPerson: EmployeePerson = { name: "John" };Для чего используется keyof и typeof
keyof - возвращает ключи через union любого типа
interface User { name: string; age: number };
type UserKeys = keyof User; // "name" | "age"
let prop: UserKeys;
prop = 'name'; // ✅ правильно
prop = 'age'; // ✅ правильно
prop = '123'; // ❌ ошибка - такого ключа нет
prop = 'email'; // ❌ ошибка - такого ключа нетtypeof - в runtime возвращает нам строку с типом, однако на этапе компиляции он вытаскивает тип и значения
const message = { id: 1, text: 'JavaScript' };
const t = typeof message; // "object" (это строка!)
// typeof в типах (compile time)
type MessageType = typeof message;
// Эквивалентно: type MessageType = { id: number; text: string; }
const userMessage: MessageType = { id: 123, text: 'Hi!' }; // ✅Мы также можем использовать их вместе, однако например в объекте и в enum мы получаем ключи, а в массиве - индексы + методы массива - там push, length и т.д.
Перечислите utility types
Utility [juː'tɪlətɪ] types - это встроенные типы, которые помогают, как-то манипулировать типами
Partial- делает все поля в типах необязательным;Required- делает все поля в типах обязательными;Readonly- создает тип, значения свойств которых нельзя изменить;Pick- у нас есть тип, и мы выбираем только те свойства, которые нам понадобитсяOmit- у нас есть тип, и мы исключаем (удаляем) те свойства, которые нам не понадобитсяExtract- из union типа берет соответствующие условиюExclude- из union типа берет НЕ соответствующие условию
Отличие Pick, Omit от Extract, Exclude заключается в том, что Pick и Omit работает с интерфейсами и типами в то время как Extract и Exclude с union типами
Record- создает тип объекта с определенными ключами и значениями -Record<Keys, Type>
type StringDictionary = Record<string, string>;
type NumberDictionary = Record<number, boolean>;
type RoleMap = Record<"admin" | "user", number>;NonNullable- удаляет null и undefined из типа
Parameters- извлекает параметры функции в виде кортежа
const multiply = (a: number, b: number): number => a * b;
type MultiplyParams = Parameters<typeof multiply>; // Результат: [a: number, b: number]ReturnType- извлекает тип значения, которое возвращает функция
function getUser(): { id: number; name: string } {
return { id: 1, name: "John" };
}
type User = ReturnType<typeof getUser>; // Результат: { id: number; name: string }Awaited- получает тип значения из Promise после его await
type A = Awaited<Promise<string>>; // Результат: string
type B = Awaited<Promise<Promise<number>>>; // Результат: number
type C = Awaited<Promise<number | Promise<string>>>; // Результат: number | string
type D = Awaited<string>; // Результат: number | string
type E = Awaited<Promise<null>>; // Результат: nullЗачем нужны условные (condition) и (mapped) types
Условные типы - позволяют выбирать динамически тип согласно условию. С помощью условного типа мы можем убрать повторяющийся код, обработать разные случае
Маппированные типы - необходимы когда мы хотим преобразовать какой-то уже существующий тип через итерацию по ключам в определенный. То есть мы можем как использовать утилиту тип Partial, а можем сами взять тип и его сделать
type MyPartial<T> = {
[K in keyof T]?: T[K];
};
type MyReadonly<T> = {
readonly [K in keyof T]: T[K];
};Что такое generic?
Generic (обобщенный тип) - механизм в TypeScript, который позволяет писать более гибкую типизацию, которая работает с разными типами данных, что позволяет в последующем удалить дублирующие функции с разными данными.
function process(input: string): string; // Объявляем сигнатуры (перегрузки)
function process(input: number): number;
function process<T>(input: T): T {
return input;
}
const result1 = process("hello"); // тип: string
const result2 = process(42); // тип: numberВ чем разница между enum и const enum?
Enum нужен для того, чтобы заменить числа на понятные названия. Разница в том, что обычный enum компилируется в JS-объект, а const enum полностью удаляется при компиляции - его значения подставляются напрямую.
// Было: if (status === 0) - непонятно
// Стало: if (status === Status.Loading) - ясноЧто такое TypeGuard?
TypeGuard - механизм в TypeScript, который позволяет сужать (narrow) типы на основе проверок через typeof, if...else, instanceOf, in (проверяет есть определенное св-в в объекте) выполняющихся в runtime.
→ Задачи по TypeScript
Необходимо протипизировать функцию, которая принимает два параметра: obj, key и возвращает значения по ключу объекта.
const X = { a: 1, b: 2, с: 3, d: 4 }
function getProperty(obj, key) {
return obj[key]
}
getProperty(X, "a");
getProperty(X, 'm')function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key]
}
getProperty(X, "a");
getProperty(X, 'm');
// Объяснения
1. Есть параметры типа T, это тип объекта, которую мы будем передавать в эту функцию в данном случае это X;
2. Второй параметр K - здесь мы используем ограничения и оно говорит, что K у нас должен быть одним из ключей объекта Т. Если мы передаем 'a', то проверка сработает, так как ключ у нас есть, а если нет, то выдаст ошибку, а вот ключа 'm' у нас нет по этому и выведится такая ошибкаНаписать реализацию существующего утилитарного типа - partial и pick
type MyPartial<Type> = {
[Key in keyof Type]? = Type[key];
}
interface User { id: number; name: string; email: string }
const user: MyPartial<User> = { name: "John" }
// Объяснения
Создаем новый тип, в котором необходимо перебрать все ключи исходного типа и каждому ключу применить определенные изменения. В данном случае мы применяем опциональность просто добавляем знак вопросаtype MyPick<T, Keys extends keyof T> = {
[k in Keys]: T[k];
};
// Объяснения
1. T - исходный тип, из которого будем выбирать свойства
2. Keys extends keyof T - ограничение, которое гарантирует, что мы можем выбирать только те ключи, которые действительно существуют в типе TНеобходимо ограничить user по объекту
Реализуйте и строго типизируйте универсальную функцию 'updateEntity', которая:
- Принимает два аргумента:
- entity - объект сущности, который нужно обновить;
- updates - объект с обновлениями, содержащий часть свойств из
entity
- Возвращает новый объект, который объединяет
entityиupdates.
interface User { id: number; name: string; email: string }
interface Post { id: number; title: string; content: string, published: boolean }
const user: User = { id: 1, name: "Alice", email: "alice@example.com"},
const updateUser = updateEntity(user, {name: "Bob"}) // Корректно
// Ожидаемый результат: {id: 1, name: "Bob", email: "alice@example.com"}
const post: Post = { id: 1, title: "hello", content: 'world', published: true},
const updatePost = updateEntity(user, { published: true }) // Корректно
// Ожидаемый результат: { id: 1, title: "hello", content: 'world', published: true}
updateEntity(user, { age: 30 }) // Ошибка "age" не существует в типе User// ... Типы User, Post
function updateEntity<T extends object>(entity: T, updates: Partial<T>):T {
return {...entity, ...updates }
}
// Объяснения
1. Создаем функцию updateEntity, внутри которого дженериком пишем параметр типа Т, и он ограничен будет только объектом. То есть Т будет объектом
2. updates: Partial<T> - все свойства делаем необязательными, то есть updates тоже объект, но у этого объекта должны быть свойства того объекта (сущности), которого мы обновляем, но мы же хотим обновить только одно свойства соответсвенно мы должны иметь возможность передавать не все свойства в интерфейс для этого мы используем утилитарный тип.
// Внизу находятся user, updateUser, post, updatePostЕсть 4 кода, необходимо разобрать его
// 1. Определите функционально утилитарного типа
type Some<T, U extends keyof T> = { [key in U]: T[key] };
// Объяснения
1. Кастомный Some позволяет создать новый тип, который содержит только выбранные свойства из исходного типа Т
2. U extends keyof T - множество ключей из параметра типа Т
3. [key in U]: T[key] - маппинг типа, создается новый тип, где значения совпадают с исходным типом, то есть из Т (исходного объекта) мы берем только те ключи, которые есть в нашем параметре типа U
interface User { id: number; name: string; email: string }
type UserPreview = Some<User, 'id' | 'name'>;// 2. Что выведет в консоль следующий код?
enum NUMBERS { ONE, TWO, THREE };
console.log(NUMBERS.ONE); // 0
// Объяснения
По умолчанию enum нумеруется с нуля => ONE (0), TWO (1), THREE (2) // 3. Чему будет равен тип U?
type T = "a" | "b" | "c";
type U = Extract<T, "a" | "d">;
// Объяснения
Утилитарный тип extract работает как фильтр. Если значение совпало со вторым значение ("a") то он оставляет этот тип, а если нет, то он исключает его// 4. Чему будет равен тип Answer?
type ObjectType = { a: string; b:boolean }
type Answer = ObjectType['a'];
// Объяснения
Извлекаю тип 'a' из ObjectType. У него свойства `a` равно string и поэтому Answer равен stringПреобразование типа
Дан код, необходимо написать свой тип так, чтобы каждое св-в внутри Status был в квадратных скобках, то есть так ["new"] | ["waiting_load"] | ['in_work'] | ['done']
type Status = "new" | "waiting_load" | 'in_work' | 'done' | 'cert_ready';
type StatusWithBrackets = Status;
const val: StatusWithBrackets = '[waiting_load]';// 1. Первый способ решение задачи - через шаблонную строку, чтобы обернуть каждый элемент в квадратные скобки
type Status = "new" | "waiting_load" | 'in_work' | 'done' | 'cert_ready';
type StatusWithBrackets = `[${Status}]`;
const val: StatusWithBrackets = '[waiting_load]';
// 2. Маппинг типов - проходимости по каждому значению и по статусу и оборачиваем в квадратные скобки, то есть для каждого ключа K мы генерируем строку в виде K и квадратные скобки
type Status = "new" | "waiting_load" | 'in_work' | 'done' | 'cert_ready';
type StatusWithBrackets = {
[K in Status]: `[${K}]`;
}[Status]
const val: StatusWithBrackets = '[waiting_load]';Необходимо записать правильный тип для MYType, чтоб переменные, которым это тип будет присвоем имели тип состоящий из ключей объекта obj
const obj = { name: "Nik", age: 25 };
type MYType = any; // Вместо any нужный тип
const var1: MYType = "name"; // Correct
const var2: MYType = "age"; // Correct
const var3: MYType = "test"; // Error
const var4: MYType = 25; // Errortype MYType = keyof typeof obj;
// Объяснения
1. typeof obj - получает тип объекта obj (в данном случае { name: string; age: number; })
2. keyof typeof obj - получает объединение всех ключей этого типа (в данном случае "name" | "age")Как можно улучшить типизацию в TypeScript
interface User { name: string; age: number };
interface UserWithRole { name: string; age: number, role: string }
// role - 'admin' или 'user'
const admin: UserWithRole = { name: "Alice", age: 30, role: "admin" }interface User { name: string; age: number };
interface UserWithRole extends User {
role: Role
}
type Role = "admin" | "user"
// Объяснения
1. Можно использовать extends (наследование), чтобы не дублировать использующий тип
2. И в роли можно указать, что она не просто строка, а 'admin' | 'user'. => пересечение типов.
3. Ну и можно вынести в отдельный тип рольНеобходимо исправить типизацию
interface Todo { id: number; title: string; done: boolean}
const createNewTodo = (todo: Todo) => {
const id = useId();
return ({ ...todo, id})
}interface Todo { id: number; title: string; done: boolean}
const createNewTodo = (todo: Omit<Todo, 'id'>): Todo => {
const id = useId();
return ({ ...todo, id})
}
1. Нет возвращаемого типа
2. Можно использовать Omit, который удалит типНапишите и типизируйте функцию, рассчитывающую стоимость с учетом скидки и рассрочки на заданное кол-в месяцев
const totalPrice = ( {price, discount, isInstallment, months } => {
// Your code here
})
const price = totalPrice({ price: 10000, discount: 25, isInstallment: true, months: 12 })
console.log(price) // 6250interface totalPriceParams {
price: number,
discount: number,
isInstallment: boolean,
months?: number
}
const totalPrice = (props: totalPriceParams) => {
// Your code here
}
const price = totalPrice({ price: 10000, discount: 25, isInstallment: true, months: 12 })
console.log(price) // 6250Типизировать функцию, чтобы возвращаемое значение было противоположным входящему. У нас на вход приходит string или number, если приходит string вернуть number и наоборот
function test(a) {}
const result1 = test('123'); // result1 будет number
const result2 = test(456); // result2 будет stringtype findStrOrNum = string | number
// Простое решение
function test(a: findStrOrNum) : findStrOrNum extends string ? number : string {}
// Через дженерик
function test2<T extends string | number>(a: T): T extends string ? number : string
// Через перегрузку
test3 = {
(a: number): string
(a: string): number
}
const test4 = function (a) {
return 1;
} as test3;
const result1 = test('123'); // result1 будет number
const result2 = test(456); // result2 будет string
// Объяснения
1. Напишем общий тип findStrOrNum;
2. Если он экстендится от строки то возвращаем number, а если нет то строкуНеобходимо описать общий тип valueOf (может быть и объектом и массивом), чтобы данные типы были верными
type obj = { key1: string; key2: number };
type Arr = number[];
type ValueOfObj = ValueOf<Obj>; // ? type ValueOfObj = string | number;
type ValueOfArr = ValueOf<Arr> // ? type ValueOfArr = numbertype obj = { key1: string; key2: number };
type Arr = number[];
type ValueOfObj = ValueOf<Obj>; // ? type ValueOfObj = string | number;
type ValueOfArr = ValueOf<Arr> // ? type ValueOfArr = number
type ValueOf<T> = T extends Arr ? number : T extends Obj ? T[keyof T]: nevertype obj = { key1: string; key2: number };
type Arr = number[];
type ValueOfObj = ValueOf<Obj>; // ? type ValueOfObj = string | number;
type ValueOfArr = ValueOf<Arr> // ? type ValueOfArr = number
type ValueOf<T> = T extends Arr<infer U> ? U : T extends Obj ? T[keyof T]: neverНеобходимо протипизировать данную функцию
interface User { age: number, name: string };
function createAndValidate(name, age) {
const newUser = {};
if (name.length = 0) {
newUser.name = name
}
if (age > 18) {
newUser.age = age
}
return newUser
}interface User { age: number, name: string };
function createAndValidate(name: string, age: number) {
const newUser: Partial<User> = {};
if (name.length === 0) {
newUser.name = name
}
if (age > 18) {
newUser.age = age
}
return newUser
}Что будет содержать Type1 и Type2
interface User { name: string; age: number; hobbies: string[] };
type Type1 = Extract<'age' | 'some' | 'hobbies', keyof User>
type Type2 = Exclude<'a' | 'b' | User, string>interface User { name: string; age: number; hobbies: string[] };
type Type1 = Extract<'age' | 'some' | 'hobbies', keyof User> // age, hobbies
type Type2 = Exclude<'a' | 'b' | User, string> // User
// Extract берет то что соответствует условию - в начале у нас есть тип из объединения строк 'age' | 'some' | 'hobbies', keyof тоже возвращает ключи - name, age, hobbies и возвращает age и hobbies, так как они одинаковые
// В начале в Exclude у нас будет тип, из которого мы будем исключать - 'a' | 'b' | User, и исключаем мы все типы string и остается только UserНеобходимо получить тип функции и тип возвращаемого значения
function log(data: string[], num: number): boolean {
console.log(data, num)
return false;
}function log(data: string[], num: number): boolean {
console.log(data, num)
return false;
}
type LogReturn = ReturnType<typeof log>
type LogParams = Parameter<typeof log>[1]Задача: как описать объект `obj` так, что бы `values` были только . А при обращении к любому `keys` объекта `obj` не терялся тип значения
const obj = {
hello: 'world',
enable: true,
whatAboutNumber: 0,
// ...other keys values
}
console.log('obj', obj.hello.toLocaleUpperCase())
console.log('obj', obj.enable)const obj: Record<string, string | boolean> = {
hello: 'world',
enable: true,
// whatAboutNumber: 0,
// ...other keys values
}
console.log('obj', obj.hello.toLocaleUpperCase())
console.log('obj', obj.enable)Напишите и типизируйте функцию, выполняющую запрос за данными по переданному URL. Выведите их в консоль в формате: "ID: id", Email: email".
const COMMENTS_URL = "https://jsonplaceholder.typicode.com/comments";
/**
* Id: 1, Email: Eliseo...
* Id: 2, Email: Eliseo_2...
*/
const getData = ( url ) => {
// Your code here
}
// 10.1. Необходимо получить тип возвращаемого значение функции (не Promise, а массив комментов)
getData(COMMENTS_URL).then((data) => {
// Your code here
})const COMMENTS_URL = "https://jsonplaceholder.typicode.com/comments";
interface Comment {
post: number;
id: number;
name: string;
email: string;
body: string
}
const getData = async ( url: string ): Promise<Comment[]> => {
const response = await fetch(url);
const data = await response.json();
return data
}
// Если мы хотим получит тип возвращаемого значение функции (не Promise, а массив комментов), то можем использовать
type res = Awaited<ReturnType<typeof getData>>Написать типизацию подходящего для двух объектов, не потерять типизацию "за" ключами в endpoints, то есть key: string и Record не подходят.
Принять, что сами ключи endpoint нам известны на этапе типизации каждого объекта: "getVtemplates" и "postVtemplates" для vtemplateObject, getReports и putReports для reportObject
Подсказка - у нас должен быть общий тип
// --- 1 --- Задает структуру объектов, не знает про конкретные объекты, и их методы// --- 2 --- Не может менять базовый тип, но знает про структуру объекта который типизируетconst templateObject = {
entity: 'template',
endpoints: {
getTemplates: {
method: "GET",
url: "template"
}
postTemplates: {
method: "POST",
url: "template"
}
}
}
const reportObject = {
entity: 'report',
endpoints: {
getReports: {
method: "GET",
url: "report"
}
postReports: {
method: "POST",
url: "report"
}
}
}// --- 1 ---
interface Endpoint {
method: string;
url: string;
}
interface ApiObject<T extends string> {
entity: string,
endpoints: Record<T, Endpoint>
}
const templateObject: ApiObject<'getTemplates' | 'postTemplates'> = {
entity: 'template',
endpoints: {
getTemplates: {
method: "GET",
url: "template"
}
postTemplates: {
method: "POST",
url: "template"
}
}
}
const reportObject: ApiObject<'getReports' | 'postReports'> = {
entity: 'report',
endpoints: {
getReports: {
method: "GET",
url: "report"
}
postReports: {
method: "POST",
url: "report"
}
}
}Мы должны проверять, если мы передали isTeamMember, то обязательно должен быть передан и yearsOfExperience
isTeamMembers и yearsOfExperience должны идти парами, если нет isTeamMembers, то и не должно быть yearsOfExperience, то есть должно вывестись ошибка
interface AvatarProps {
imgSrc: string;
isTeamMembers?: boolean;
yearsOfExperience?: number;
}
const avatarProps1: AvatarProps = { imgSrc: '...' }
// @ts-expect-error
const avatarProp2: AvatarProps = { imgSrc: '....'; isTeamMembers?: true; }
const avatarProp3: AvatarProps = {
imgSrc: '-----';
isTeamMembers?: true;
yearsOfExperience?: 3;
}type AvatarProps = {
imgSrc: string;
} & (
| { isTeamMember?: never; yearOfExperience?: never}
| { isTeamMember: true; yearOfExperience: true}
)
// Объяснения imageSource будет постоянным и мы этот интерфейс через пересечение & выбираем с чем объединить либо с вариантом isTeamMember и тогда не yearsOfExperience либо с тем и с темReact
Что такое react и перечислите особенности его?
Это javascript - библиотека с открытым исходным кодом разработанной фейсбуком. Предназначена для создания пользовательских интерфейсов.
К особенностям относится:
-
компоненты;
-
jsx;
-
хуки;
-
использование виртуального дома вместо реального;
Что будет быстрее - через getElementById стиль поменять или через react?
Что такое компонент? И почему они должны начинаться с большой буквы?
Компоненты нужны для создания ui (пользовательского интерфейса) в react. По своей структуре компоненты представляются небольшие блоки (куски) кода, которые мы можем использовать в разных местах нашего приложения. Они создаются с помощью классов, что является устаревшим методом, и с помощью функций.
Возможно это связано с соглашением самого react и указывает, что мы используем react с jsx. Если мы напишем компонент с маленькой буквы, то у нас будет ошибка.
Что такое jsx?
JSX - расширения языка JS, который позволяет разработчику объединить JavaScript-кода и HTML/XML в один файл. По сути, JSX - это синтаксический сахар React.createElement.
Можно ли использовать react без JSX?
Да, можно, нам просто нужно вместо компилятора уже самим писать return React.createElement.
function Greeting(props) {
return React.createElement('div', null, 'Hello, ' + props.name + '!');
}
Разница между компонентом и элементом?
Компонент возвращает jsx-разметку в котором хранятся элементы, сам компоненты мы не видим в браузере, а вот элементы мы можем видеть.
Разница между контролируемым и неконтролируемым компонентом?
Контролируемый компонент - это input за состоянием (state), которого мы можем следить. Например с помощью метода setState или использования хука useState
Неконтролируемый компонент - это input, состояние которого хранится внутри дома и управляется браузером, и чтобы его получить (значения) нужно исп refs.
Что такое чистые компоненты (PureComponent)?
Чистый компонент — это компонент, у которого нет побочных эффектов, а также он избегает ненужного повторного рендеринга путем неглубокое сравнения предыдущего состояния и пропса с новым состоянием и пропсом, и если они одинаковые, то компонент не перерисовывается
Чем фрагмент `<>` отличается от `div`?
В react необходимо оборачивать все теги в один общий контейнер и нам с этим помогает как фрагмент так и div. Фрагмент представляет собой пустые теги, но это сокращенный вариант от слова Fragment. Отличия:
-
Когда мы пишем div у нас создается дополнительный класс, а когда фрагмент то он пропускает добавления класса и сразу же переходит к дочерним тегам.
-
Во фрагменте могут возникнуть проблемы с key, если мы исп сокращенный вариант, чтобы работать с ключом нам нужно импортировать из библиотеки react фрагмент
Что такое props? И чем он отличается от state?
Props расшифровывается как properties, он необходим нам для передачи каких-то данных от родительского компонента к дочернему, и потом на его основе он отрисовывает jsx разметку.
- Отличие:
- Props мы можем передавать компоненту, в то время как state находится внутри компонента.
- Пропсы иммутабельные (неизменяемые) в то время как state можем изменить внутри компонента через хук useState.
Стоит отметить, что никто нам не запрещает передавать state в качества пропса, однако state управляется только в родительском компоненте, то есть дочерним компонент не сможет влиять на состояние родительского. Для того, чтобы дочерний смог взаимодействовать с родительским нужно использовать callback
Для чего нужен key ? Приведите пример его использования?
Когда мы хотим отрисовать список, то нам необходимо ключи. Они помогают react определить, какие элементы были изменены, добавлены или удалены. В качестве ключей мы используем в основном ID. Если мы не укажем ключи, то он будет работать однако в console будет отображаться warning о том, что необходимо их добавить.
Дополнительный вопрос: почему index в key не лучшая практика?
- Могут возникнуть ошибка неправильной сортировка элементов списка, а также вставке новых элементов или удалении
Что такое «бурение пропсов» (Prop Drilling)? Как его избежать?
Например: у нас есть большая вложенность компонентов, и нам необходимо передать пропсы в дочерние. Если это небольшая вложенность, то с этим проблем нет. А если это большое приложение, то очень затруднительно поддерживать, так как постоянно в дочерние компоненты необходимо добавлять пропсы и вытаскивать их. Чтобы решить данную проблему есть хук useContext или можно использовать state менеджмент redux, redux toolkit, effector
Что такое виртуальный дом и как он работает?
Virtual-dom - это облегченная (легковесная) копия реального дома, которая представляет собой дерево объектов. Когда состояние компонента изменяется, то react обновляет виртуальный DOM, а после обновления виртуальный дом текущей версии сравнивается с предыдущим домом, находить изменения и вносит их уже в настоящий дом.
- Дополнительный вопрос: что появляется первым Дом или virtual-dom?
Сначала появляется дом, а затем на его основе виртуальный, потом виртуальный дом сравнивается с предыдущим домом и если видит изменения, то вносит уже в настоящий дом
- Дополнительный вопрос: react увидел, что дивки разные, то как он будет работать?
Сначала он отрисует в virtual-доме, а потом возьмет эту дивку и заменит его в реальном доме. А если они одинаковые, то будет смотреть по содержанию
Какая разница между теневым домом и виртуальным домом?
Это разные понятие, однако в чем они схожи так в том, что они помогают решить проблемы с производительностью.
Виртуальный дом создает копию всего объекта дома, а теневой дом создает только небольшую часть.
Теневой дом - концепция браузера и она необходима когда мы хотим какой-то элемент хотим полностью изолировать, чтобы к нему даже не применялись глобальные стили.
Расскажите про методы жизненные циклы компонента, и что в них входят (имеется ввиду какие методы исп внутри каждого цикла)?
У компонента есть три метода жизненного цикла:
- mounting (монтирование) - это рождения компонента, это процесс создания компонента и его добавления в DOM;
- update (обновления) - можно сравнить с ростом и то что компонент живет;
- unmounting (размонтирование) - это уже смерть человека;
Существует разные методы жизненного цикла, которые react предоставляет на разных этапах жизненного цикла компонента. Жизненный цикл делится на 4 части: инициализация, монтаж, обновления и размонтирования.
-
За инициализацию отвечает конструктор;
-
За монтаж отвечает определенные методы: конструктор, рендер, но больше хочется обратить внимания сomponentDidMount() - метод, который вызывается после того, как компонент был добавлен в DOM
-
За обновления отвечает: shouldComponentUpdate(), вызывается перед повторным рендерингом компонента и если нет никаких изменений, то он предотвратит повторный рендеринг, а если есть то он вызовет рендерит и вызовет метод componentDidUpdate, что означает, что компонент обновился;
-
За размонтирования отвечает componentWillUnmount(), вызывает перед удаление компонента, что означает конец жизненного цикла компонента
В хуках за все это отвечает хук useEffect;
Что такое хуки и расскажите про преимущество и недостатки хуков?
Хуки появились в 16 версией и используется они в функциональном компоненте. Хуки представляют из себя функции, c помощью которых мы можем подписаться на какое-то состояние, сохранять его а потом обновлять данное состояние (useState). Также мы можем делать запросы на сервер с помощью, работать с контекстом и много другое
К преимуществам хуков относится:
- Переход с классовых компонентах на функциональный. Поясню: раньше чтобы сделать какое-то дефолтное состояние необходимо было написать 6-7 строк кода сейчас это можно заменить одним useState
- Его легче читать
- Также с помощью одного хука useEffect можно описать жизненный цикл компонента хотя в классах нам необходимо было использовать componentDidMount(), componentWillUnmount()
К недостатком относится:
- Мы не можем исп хуки в классах
- Проблема с пропс дриблингом, у нас есть для этого хука useContect(), но у него есть ряд проблем. Легче использовать state-менеджмент
Расскажите про основные хуки: useState(), useEffect(), useContect()?
- Хук
useState()- это функция, которая меняет состояние. ХукuseState('')принимает начального значение, которая пишется внутри фигурных скобок и возвращает массива с 2 параметрами - первый параметр это текущее состояние, а вторым является функция, которая обновляет состояние:[state, setState].
const [state, setState] = React.useState('')
- Хук
useEffect()- необходим нам для выполнения каких-то side-effect (побочных эффектов), там запрос на сервер, setTimeOut (setInterval), обращения к дому и т.д.
Дополнительный вопрос: Когда срабатывает useEffect? - useEffect срабатывает после того как отрисовал наш компонент. А также:
- Если мы не написали никакую зависимость, то он будет вызываться всегда;
- Если мы передали какую-то зависимость, то он срабатывается при первом рендеринг и когда меняется состояние.
- А если мы написали зависимость но не передали ничего, то срабатывает только при монтирования компонента
Одна из функций хука позволяет нам останавливать побочные эффекты, которые больше не нужно выполнять, до того, как наш компонент будет размонтирован. Нам нужно просто написать return внутри useEffect
useEffect(() => {
// the side effect takes place here.
return () => {
// the cleanup function
}
}, [])
Link: useEffect
- Хук
useContect()придумали для избавления так называемого пропс dribbling - это когда в родительском компоненте есть какие-то данные, которые необходимы передать дочерним даже там где они не используются, чтобы отказаться от пропса дриблинга был придуман данный хук.
Контекст позволяет передать данные от родительского компонента сразу к компонента, которому это нужно
Расскажите про хуки: useMemo, useCallback, а также про HOC: React.memo
-
Хук
useMemo- нужен для оптимизации нашего приложения и избежания повторных рендеринг. Он кеширует результат Он работает следующим образом: сохраняет (кеширует) результат и меняется только тогда, когда приходят новые входные данные, которые мы передадим в зависимости. Если мы оставим зависимости пустые, то он запомнит результат и всегда будет возвращать сохраненный результат. -
Хук
useCallBack()- похож наuseMemo, однако он кеширирует callback-функцию функцию. Я бы еще добавил, что useCallback стоит использовать вместе с React.memo, по отдельности их использовать бессмысленно, так как в любом случае будет происходить перерисовка страницы, а вот если в дочернем компоненте используем мемо, то перерисовка не будет происходить.
Компонент высшего порядка (HOC) - функция, которая принимает в качестве аргумента другой компонент и возвращает новый компонент с расширенным функционалам. К хокам можно отнести: React.memo, withRouter
Основным отличием хука useMemo от хока React.memo заключается в том, что React.memo используется для оптимизации компонента, тогда как useMemo используется для мемоизации вычислений внутри компонента, которые могут быть дорогостоящими и занимать много времени.
Когда стоит использовать useCallback, а когда нет ?
Расскажите про хуки: useReducer(), useRef()?
Хук useReducer() - необходим когда у нас есть несколько state, которые обновляются вместе и когда нужно учитывать другие состояния.
- Например при запросе на сервер, нам необходимо: один state для загрузки, второй для ошибка, а третий для постов. Мы можем объединить в один общий хук useReducer
Хук useRef() - используется для работы с дом элементами напрямую, и в параметры у него приходят начальное значение, если данного значения нет, то пишем null.
Ключевое отличие между useState и useRef заключается в том, что useState используется для отслеживания состояния компонента и вызывает перерендеринг, тогда как useRef используется для хранения изменяемых значений, которые не вызывают перерендеринг компонента.
Что такое batching
Что такое Flux?
Flux - архитектура, которая придумала предложила фейсбук для решения некоторые проблемы. Он построен на однонаправленном потоке (передачи) данных между компонентами. Flux содержит 4 компонента - это action (действия), dispatcher (диспетчер), store (хранилище), view (представления).
Если говорить о них по подробней, то action - данные, которая передается диспетчеру. Диспетчер принимает эти данные и уведомляет store об этом. А store в свою очередь содержит состояния приложение и логику, после view запрашивает данные у store и передает его другим (дочерним) компонентам.
Что такое redux и назовите его основные принципы?
Redux представляет собой контейнер для управления состоянием приложения, и он похож на Flux. К основным принципам redux относится:
- Единый store, то есть у него один
- состояние предназначен только для чтения. А чтобы изменить состояние необходим action
- все изменения происходит только с помощью чистых функций.
Стоит отметить, что как у react - однонаправленный поток данных (он идет от родителя к потомку), так и у flux и redux.
Разница между Flux и Redux?
- flux появился раньше, чем redux. И как раз на основе flux был сделан redux;
- У flux есть много store, а у redux он один;
- У flux состояние мутирует, а у redux не мутирует;
Разница между Redux и React.Context?
Стоит начать с того, что redux более мощнее и у него больше функций чем в контексте. Например в контексте: нет reducer и thunk. Вместо thunk нам надо писать все с хуком useEffect(). А вся логика контекст его в компоненте, что делает компонент более большим и громоздким. Отличительными чертами также является:
- В redux мы используем useDispatch(), а в контексте useUpdate();
- В контексте нам нужно постоянно писать спред операторы, а вот в redux-toolkit можно этого не делать, так как он под капотом за нас это делает.
Что такое reducer?
Reducer - чистая функция, которая принимает два параметра:
- state;
- action;
Доп.вопросы:
- React Fiber и процесс обновления Virtual DOM
- Что такое батчинг в React?
- Как работает useLayoutEffect в React и чем он отличается от useEffect?
- хук useImperativeHandle
- React.lazy и Suspense — ленивые компоненты в React
- Правила использования хуков в React
- Порядок рендера компонентов и вызова хуков в React
- Причины перерисовки компонентов в React
- Что такое виртуализация и зачем она нужна
- Что такое HOC и зачем он нужен
- Что такое React.PureComponent
- Что такое React.Portal
- Что такое React.Fragment
- Что такое React.Children
- Error Boundaries в React
- Reconciliation (Согласование) в React
- Synthetic Events в React React.StrictMode
- Refs в React (useRef, createRef, forwardRef)
HTTP
Что такое HTTP и как он работает?
HTTP (Hypertext Transfer Protocol)- протокол прикладного уровня. Он используется для обмена данными между клиентом и сервером. Например когда пользователь кликает на любую ссылку в браузере, то браузер отправляет HTTP-запрос на сервер, тот обрабатывает его, и отправляет HTTP-ответ
В чем отличие между HTTP и HTTPS?
Основное отличие заключается в безопасности, у HTTPS все данные передаются в зашифрованном виде, что защищает от перехвата информации от клиента, его кошелька и т.д.
Порты разные - у http 80, а у https 443
Когда мы пытаемся зайти на сайт с http-протоколом гугл сообщает, что данный сайт небезопасный.
Из чего состоит (структура) http-запроса?
Структура HTTP-запроса состоит из 4 кл.элементов:
- Стартовая строка состоит из методов (Get, post, put), пути (url) и версии протокола HTTP;
- Заголовки (Headers) HTTP - метаинформация по типу, host, типа контента json;
- Пустую строку (обязательный) - разделитель между заголовками и телом запроса
- Тело запроса (необязательный) - используется для передачи данных на сервер, например, при использовании методов POST, PUT и PATCH
Какие есть методы в HTTP-запрос?
Всего 9 методов, разделяются они на основные и служебные.
1. К основным относится - Get (__для-получения-данных__), post (__для-отправки-данных__), put(__для-полного-обновления-данных__), delete (__для-удаления-чего-либо__), patch(__для-частичного-редактирования-данных__)
2. А к служебные: Head (__для-получения-только-заголовков-(HEAD)__), Options (____для-узнания-поддерживаемых-методов-и-политик-CORS__), Trace(__для-диагностики-между-прокси-и-сервером__), Connect(__для-подключения-к-HTTPS-через прокси__)
Что такое кеширование и какие методы у нас кешируется, а какие нет?
Кеширование - механизм, который сохраняет временно данные на стороне клиента, чтобы ускорить их последующую загрузку и снизить нагрузку на сервер.
Кешуруемые методы - это GET, HEAD
Разница между GET- и POST-запросами?
GETиспользуется для получения данных, аPOSTдля отправки данных.GET- индопотентен, а post нетGET-запросы у нас кешируется, аPOST-запросы нет.
Post можно закешировать на определенное время, если мы укажем если Cache-Control max-age=3600, но это не лучшая практика и браузер может заигнорировать кеширования
- Если говорить про передачу данных, то у
GETпараметры передают в url-строке, а уPOSTв теле запроса body
Разница между PUT- и POST-запросами?
-
PUT-запрос необходим для обновления уже существующих данных или если этих данных нет, то для создания новых данных аPOSTдля создания чего-то нового либо отправки каких-то данных -
PUT-запрос идемпотентен, в то время какPOST-запрос нет. Идемпотент означает, что каждый раз когда мы делаем одно и тоже действия мы ожидаем одинаковый результат, однако у поста каждое отправления создается новый результат
Расскажите про коды состояния?
1. 1xx - носит информационный характер, например сервер получил headers (заголовки) твоего запроса и готов принять тело. Продолжай отправку;
2. 2xx - запрос был успешно выполнен;
3. 3xx - перенаправления, теперь сайт находится по новому адресу;
4. 4xx - ошибка на стороне клиента, запрос не тот передали или еще что-то;
5. 5xx - ошибка на стороне сервера
В чем разница между HTTP/1.1, HTTP/2 и HTTP/3
-
В первой версии HTTP данные передавались в виде текса, а это в свою очередь увеличивало размер и загрузку, во второй версии уже используются фреймы, разделяя запрос и ответ на маленькие управляемые фреймы
-
В первой версии не было Сжатия и все передавалось как есть, во второй же сживаются заголовки
-
В первой версии не было мультипликисирование - это когда на одном соединнения можно было отправлять несколько запросов, оно появилось во второй. В первой нужно было открывать несколько соединений
А в 3 версии решается проблема Head-of-Line Blocking, если во второй версии потеря одного пакета тормозил все потоки, то в 3 версии каждый поток независим и пакеты в одном не влияет на другие
Что такое HTTP cookie? Для чего они используются?
HTTP cookie – это небольшие фрагменты данных (каждый до 4 КБ), которые хранятся в браузере пользователя и отправляются в каждом запросе. Обычно они устанавливаются сервером с помощью заголовка Set-Cookie, но могут создаваться и через JavaScript. Количество кук на один домен ограничено (обычно 100-180 в современных браузерах). Время жизни куков можно сделать временным, пока пользователь не закроет браузер, или постоянным, там по стечению определенного времени через max-age
Куки используются для:
- управления сеансом - логины, корзины с покупками;
- мониторинга - отслеживания поведения пользователей;
- Предпочтения пользователей (персонализация) - язык интерфейса, тема;
Что такое веб-хранилище (web storage) и разница между sessionStorage и localStorage?
Web-storage - это инструмент, который позволяет хранить данные в браузере в виде: ключ и значение.
Существует два вида хранения информации: sessionStorage (данные хранятся пока в браузере не закроем вкладку) и localStorage (данные хранятся пока не исякнет период хранения либо пока не отчистим кеш)
Если мы откроем рядом еще одну session storage то данные будут создаваться снова, в отличии от local storage, который доступен из любой вкладке.
Доп.вопросы:
-
А как вы будете хранить объект в localStorage? - При записи JSON.stringify(), а при чтении JSON.parse(), так как апи работает только со строками
-
Что произойдёт с localStorage в режиме инкогнито? - Будет работать, но все данные удаляться после закрытия всех вкладок приватного режима
-
В чём основное отличие от Cookies? - Мы не отправляем на сервер каждый HTTP-запрос, у нас нет жесткого ограничения 4KB
-
Как обработать ситуацию, если localStorage переполнен? - Браузер выбросит исключения QuotaExceededError, если у нас localStorage переполнен. Для обработки нужно обернуть вызов setItem() в блок try...catch и в блоке catch проверить error.name === 'QuotaExceededError'."
Что такое CORS?
CORS (Cross-Origin Resource Sharing) — это механизм безопасности браузера, который с помощью HTTP-заголовков, разрешают или запрещают веб-странице брать ресурсы с других доменов. Сервер указывает в ответе, с каких источников разрешены запросы, а браузер применяет эти правила.
Что такое WebSocket? В чем принцип его работы?
WebSocket - протокол для постоянного обмена данными между браузером и сервером в реальном времени без постоянных перезапросов.
Например: вебсокеты используются - в чатах, на сайтах обменников криптовалюты, в онлайн играх и т.д.
Если HTTP работает по принципу запрос-ответ, то вебсокет установляет двустореннее соединения, где сервер сам отправляет данные в любой момент времени
Что такое аутентификация, авторизация и логинизация?
Логинизация - ввод логина и пароля для входа в систему
Аутентификация - процесс проверки пользователя, сравнивается логин и пароль который ввел пользователь и если он совпадает с их базой данный, то дает доступ
Авторизация - процесс прав пользователя. Грубо говоря что может человек делать, а что нет
Что такое JWT-токен, где он хранится?
Во время аутентификации, когда происходит проверка логина и пароля с базой данных, то он отправляет JWT-токен. Этот токен на фронте мы должны обработать и если он имеется, то дать доступ ко входу в личный кабинет