Frontend | Вопросы собесов
Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @sendme_ads
Показати більше📈 Аналітичний огляд Telegram-каналу Frontend | Вопросы собесов
Канал Frontend | Вопросы собесов (@easy_javascript_ru) у мовному сегменті Російська є активним учасником. На даний момент спільнота об'єднує 17 471 підписників, посідаючи 7 451 місце в категорії Технології та додатки та 37 672 місце у регіоні Росія.
📊 Показники аудиторії та динаміка
З моменту свого створення невідомо, проект продемонстрував стрімке зростання, зібравши аудиторію у 17 471 підписників.
За останніми даними від 26 жовтня, 2026, канал демонструє стабільну активність. Хоча за останні 30 днів спостерігається зміна кількості учасників на -202, а за останні 24 години на -11, загальне охоплення залишається високим.
- Статус верифікації: Не верифікований
- Рівень залученості (ER): Середній показник залученості аудиторії становить 6.62%. Протягом перших 24 годин після публікації контент зазвичай збирає 4.38% реакцій від загальної кількості підписників.
- Охоплення публікацій: В середньому кожен допис отримує 1 156 переглядів. Протягом першої доби публікація в середньому набирає 765 переглядів.
- Реакції та взаємодія: Аудиторія активно підтримує контент: середня кількість реакцій на один пост – 4.
- Тематичні інтереси: Контент зосереджений навколо ключових тем, таких як ставь, браузер, html, border, flex.
📝 Опис та контентна політика
Автор описує ресурс як майданчик для висловлення суб'єктивної думки:
“Сайт: https://easyoffer.ru/
Все каналы: t.me/+xGeAw6ckJ4liYzQy
Контакт для рекламы: @sendme_ads”
Завдяки високій частоті оновлень (останні дані отримано 27 жовтня, 2026), канал підтримує актуальність та високий рівень охоплення публікацій. Аналітика показує, що аудиторія активно взаємодіє з контентом, що робить його важливою точкою впливу в категорії Технології та додатки.
var globalVar = 'Я глобальная переменная';
function testFunction() {
console.log(globalVar); // Доступно
}
testFunction();
console.log(globalVar); // Доступно
🚩Функциональная область видимости
Переменные, объявленные с помощью var внутри функции, имеют область видимости, ограниченную этой функцией. Они недоступны за её пределами.
function testFunction() {
var functionVar = 'Я внутри функции';
console.log(functionVar); // Доступно
}
testFunction();
console.log(functionVar); // Ошибка: переменная functionVar недоступна
🚩Блочная область видимости
Переменные, объявленные с помощью let и const, имеют область видимости, ограниченную ближайшим блоком {}.
if (true) {
let blockVar = 'Я внутри блока';
console.log(blockVar); // Доступно
}
console.log(blockVar); // Ошибка: переменная blockVar недоступна
🚩Область видимости модуля (Module Scope)
При использовании модулей (например, import и export в ES6), все переменные и функции в модуле имеют собственную область видимости. Они не попадают в глобальную область видимости.
export const myVar = 'Я переменная из модуля';
import { myVar } from './module1.js';
console.log(myVar); // "Я переменная из модуля"
Ставь 👍 и забирай 📚 Базу знанийasync
Используется перед объявлением функции. Это позволяет функции автоматически возвращать промис. Если эта функция возвращает не промис, то возвращаемое значение будет автоматически обернуто в промис.
async function fetchData() {
return 'данные';
}
fetchData().then(data => console.log(data)); // выводит "данные"
🚩Ключевое слово await
Используется для ожидания результата промиса внутри асинхронной функции async. Оно приостанавливает выполнение асинхронной функции до тех пор, пока промис не выполнится (т.е. не будет разрешен или отклонен). ЕЕ можно использовать только внутри асинхронных функций.
async function fetchData() {
let data = await fetch('https://api.example.com/data');
let json = await data.json();
return json;
}
🚩Плюсы
➕Улучшение читаемости кода
Асинхронный код, написанный с использованием async/await, выглядит более структурированным и похожим на синхронный код, что упрощает его понимание
➕Упрощение обработки ошибок
В асинхронных функциях с await можно использовать стандартный синтаксис try/catch для обработки ошибок, что делает код единообразнее.
➕Избегание "callback hell"
Использование async/await позволяет избежать сложностей с вложенными коллбэками, которые могут возникнуть при использовании промисов или старого стиля асинхронного кода с коллбэками.
Ставь 👍 и забирай 📚 Базу знанийem зависит от размера шрифта родителя (font-size).
.parent {
font-size: 20px;
}
.child {
font-size: 1.5em; /* 1.5 * 20px = 30px */
}
Но если .child вложен в .parent, то он наследует font-size, а его em вычисляется относительно родителя.
.parent {
font-size: 20px;
}
.child {
font-size: 1.5em; /* 30px */
}
.grandchild {
font-size: 2em; /* 2 * 30px = 60px */
}
🟠Как работает `rem`?
rem всегда зависит от font-size у <html>.
html {
font-size: 16px;
}
.container {
font-size: 2rem; /* 2 * 16px = 32px */
}
🟠Когда использовать `em`, а когда `rem`?
Используйте rem, если нужно, чтобы шрифты и размеры были предсказуемыми
Используйте em, если хотите, чтобы элементы зависели от родителя
Ставь 👍 и забирай 📚 Базу знанийtransform с функцией rotate. Это свойство позволяет применять различные трансформации к элементам, включая вращение, масштабирование, смещение и наклон.
🚩Пример использования
.rotated-box {
width: 100px;
height: 100px;
background-color: lightblue;
transform: rotate(45deg);
}
🚩Объяснение
Основной синтаксис
🟠Угол поворота элемента. Может быть положительным или отрицательным значением в градусах (deg), радианах (rad), градусах (grad) или оборотах (turn).
transform: rotate(угол);
🟠Параметры
Угол поворота элемента. В данном случае элемент поворачивается на 45 градусов по часовой стрелке.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.rotated-box {
width: 100px;
height: 100px;
background-color: lightblue;
transform: rotate(45deg);
}
</style>
</head>
<body>
<div class="rotated-box"></div>
</body>
</html>
🚩Пояснение
🟠Свойство `transform`
Позволяет применять различные визуальные эффекты к элементу, такие как вращение, масштабирование и смещение.
🟠Функция rotate
Используется для вращения элемента на заданный угол. Положительные значения поворачивают элемент по часовой стрелке, отрицательные — против часовой стрелки.
🚩Использование в реальных проектах
🟠Вращение элементов
Вращение элементов может использоваться для создания интересных визуальных эффектов, таких как поворот иконок, изображений или блоков текста.
🟠Анимация
В комбинации с анимацией (@keyframes и transition), вращение может создавать динамичные и интерактивные пользовательские интерфейсы.
Ставь 👍 и забирай 📚 Базу знанийclass Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
increment = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<button onClick={this.increment}>
Счетчик: {this.state.count}
</button>
);
}
}
Функциональный компонент (хуки делают код проще)
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Счетчик: {count}
</button>
);
}
🟠Легче управлять жизненным циклом (useEffect vs componentDidMount)
В классах жизненный цикл* компонента состоит из нескольких методов (componentDidMount, componentDidUpdate, componentWillUnmount).
class Timer extends React.Component {
constructor(props) {
super(props);
this.state = { time: 0 };
}
componentDidMount() {
this.timer = setInterval(() => {
this.setState({ time: this.state.time + 1 });
}, 1000);
}
componentWillUnmount() {
clearInterval(this.timer);
}
render() {
return <p>Время: {this.state.time} секунд</p>;
}
}
Функциональный компонент (хуки делают все проще)
function Timer() {
const [time, setTime] = useState(0);
useEffect(() => {
const timer = setInterval(() => setTime(t => t + 1), 1000);
return () => clearInterval(timer);
}, []);
return <p>Время: {time} секунд</p>;
}
🟠Лучшая производительность (меньше потребления памяти)
Классовые компоненты используют экземпляры классов, а функциональные компоненты – просто функции.
Создают экземпляры this
Обрабатывают setState
Хранят лишние связи и контексты
Не создают this
Используют только нужные данные
Оптимизируются через React.memo
const Button = React.memo(({ onClick }) => {
console.log("Ререндер кнопки");
return <button onClick={onClick}>Нажми</button>;
});
function App() {
const [count, setCount] = useState(0);
const increment = useCallback(() => setCount(c => c + 1), []);
return (
<div>
<p>Счетчик: {count}</p>
<Button onClick={increment} />
</div>
);
}
🟠Легче переиспользовать логику (React Hooks vs HOC/Render Props)
Раньше в классах код переиспользовали через HOC и Render Props, но это делало код сложным.
function withLogging(WrappedComponent) {
return class extends React.Component {
componentDidMount() {
console.log("Компонент монтирован");
}
render() {
return <WrappedComponent {...this.props} />;
}
};
}
Хуки (useEffect) делают код чище
function useLogger() {
useEffect(() => console.log("Компонент монтирован"), []);
}
function MyComponent() {
useLogger();
return <p>Привет, мир!</p>;
}
🟠Функциональные компоненты – будущее React
React официально рекомендует использовать функциональные компоненты
Dan Abramov (разработчик React)
Новые фичи React (Suspense, Server Components) создаются для функциональных компонентов
Классы не работают в React Server Components
Большинство современных библиотек (Redux Toolkit, React Query) рассчитаны на хуки
Ставь 👍 и забирай 📚 Базу знаний📂 60 минут технических вопросов и задач, которые встречаются на собеседованиях 📂 Подробный фидбек: что получилось хорошо, где потерял баллы и что стоит подтянутьПосле мока сможешь самостоятельно разобрать обратную связь или проработать слабые места с ментором. Так будет проще закрыть пробелы и подготовиться к следующему грейду и росту зарплаты. Мок проходит в рамках менторской программы Шортката. У нас 150+ менторов из Авито, Сбера, VK, WB, Uber и Booking, а наши менти получили уже 500+ офферов 🔥 Открыли всего 50 мест по специальной цене 2000 ₽ вместо 7900 ₽ Для записи переходи в бота → @shortcut_front_bot Реклама. О рекламодателе.
<div class="button">Кнопка</div>
.button {
background: blue;
color: white;
}
Плохой пример без БЭМ
.container .button {
background: blue;
}
🟠Элементы (`__`) зависят только от своего блока
Стили элемента никогда не зависят от родителя — только от блока.
<div class="card">
<h2 class="card__title">Заголовок</h2>
<p class="card__text">Текст карточки</p>
</div>
.card__title {
font-size: 20px;
}
.card__text {
color: gray;
}
🟠Модификаторы (`--`) изменяют только нужные стили
Модификаторы позволяют изменять внешний вид без переписывания базовых стилей.
<button class="button button--red">Кнопка</button>
<button class="button button--blue">Кнопка</button>
.button {
padding: 10px;
border-radius: 5px;
}
.button--red {
background: red;
}
.button--blue {
background: blue;
}
🟠Имена классов уникальны, нет глобальных стилей
В БЭМ не используется tag {} или id {} — только классы. Это предотвращает конфликты стилей.
h1 {
color: red;
}
БЭМ-версия
.card__title {
color: red;
}
Ставь 👍 и забирай 📚 Базу знанийelement.
Когда браузер загружает страницу, он парсит HTML и создает DOM-объекты, в которых атрибуты превращаются в свойства. Однако атрибуты и свойства не всегда совпадают!
🟠Атрибуты (`attributes`)
Хранятся в HTML.
Всегда являются строками.
Их можно получить с помощью .getAttribute() и изменить через .setAttribute().
Они не меняются динамически при изменении свойства элемента в JS.
<input id="myInput" type="text" value="Hello">
const input = document.getElementById("myInput");
console.log(input.getAttribute("value")); // "Hello"
🟠Свойства (`properties`)
Хранятся в объекте элемента (HTMLElement).
Имеют разные типы данных (строки, числа, булевые и т. д.).
Меняются динамически при взаимодействии с DOM.
console.log(input.value); // "Hello"
input.value = "New text"; // Меняем свойство
console.log(input.getAttribute("value")); // "Hello" (атрибут НЕ поменялся)
console.log(input.value); // "New text" (свойство изменилось)
Пример с checked у чекбокса
<input type="checkbox" id="myCheckbox" checked>
const checkbox = document.getElementById("myCheckbox");
console.log(checkbox.getAttribute("checked")); // "checked" (атрибут есть, значит включен)
console.log(checkbox.checked); // true (свойство JS - boolean)
checkbox.checked = false; // Меняем состояние чекбокса
console.log(checkbox.getAttribute("checked")); // "checked" (атрибут не поменялся!)
console.log(checkbox.checked); // false (свойство изменилось)
🟠Как правильно работать с атрибутами и свойствами?
Если хотите работать с DOM → используйте свойства (element.value, element.checked и т. д.).
Если хотите работать с атрибутами в HTML → используйте .getAttribute() и .setAttribute().
const img = document.querySelector("img");
// Меняем атрибут src
img.setAttribute("src", "new-image.jpg");
// Меняем свойство width
img.width = 300;
Ставь 👍 и забирай 📚 Базу знанийprops
useReducer работает как Redux, но проще
const AuthContext = createContext();
function authReducer(state, action) {
switch (action.type) {
case "LOGIN":
return { ...state, isAuthenticated: true, user: action.payload };
case "LOGOUT":
return { ...state, isAuthenticated: false, user: null };
default:
return state;
}
}
function AuthProvider({ children }) {
const [state, dispatch] = useReducer(authReducer, {
isAuthenticated: false,
user: null,
});
return (
<AuthContext.Provider value={{ state, dispatch }}>
{children}
</AuthContext.Provider>
);
}
function LoginButton() {
const { dispatch } = useContext(AuthContext);
return (
<button onClick={() => dispatch({ type: "LOGIN", payload: "Иван" })}>
Войти
</button>
);
}
🚩Zustand
Проще Redux, но с теми же возможностями
Нет лишних actions и reducers, только функции
import { create } from "zustand";
const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}));
function Counter() {
const { count, increment } = useStore();
return <button onClick={increment}>Счетчик: {count}</button>;
}
🚩Recoil
Идеален для React-приложений
Гибче, чем Redux, с концепцией "атомов" (раздельные состояния)
import { atom, useRecoilState } from "recoil";
const countState = atom({
key: "count",
default: 0,
});
function Counter() {
const [count, setCount] = useRecoilState(countState);
return <button onClick={() => setCount(count + 1)}>Счетчик: {count}</button>;
}
🚩Jotai
Напоминает Recoil, но без сложных концепций
Поддерживает React Suspense и асинхронные состояния
import { atom, useAtom } from "jotai";
const countAtom = atom(0);
function Counter() {
const [count, setCount] = useAtom(countAtom);
return <button onClick={() => setCount(count + 1)}>Счетчик: {count}</button>;
}
🚩MobX
Автоматически отслеживает изменения состояния
Удобен для сложных приложений
import { makeAutoObservable } from "mobx";
import { observer } from "mobx-react-lite";
class CounterStore {
count = 0;
constructor() {
makeAutoObservable(this);
}
increment() {
this.count++;
}
}
const store = new CounterStore();
const Counter = observer(() => (
<button onClick={() => store.increment()}>Счетчик: {store.count}</button>
));
🚩XState
Подходит для сложных логик (например, UI-анимаций, состояний формы)
Удобно описывать последовательности действий
import { createMachine, interpret } from "xstate";
const toggleMachine = createMachine({
id: "toggle",
initial: "inactive",
states: {
inactive: { on: { TOGGLE: "active" } },
active: { on: { TOGGLE: "inactive" } },
},
});
const service = interpret(toggleMachine).start();
service.send("TOGGLE"); // Меняет состояние
Ставь 👍 и забирай 📚 Базу знаний