⚡ Задача дня
❓ Что выведет этот код?
✅ Ответ
Промис создан
Код завершён
Успех!
Если возникли трудности, читай про эту тему здесь:
https://learn.javanoscript.ru/promise-basics
Промисы — мощная вещь, главное понять, как они работают. Ты справишься! 🚀
#javanoscript #собеседования
❓ Что выведет этот код?
const promise = new Promise((resolve, reject) => {
console.log("Промис создан");
resolve("Успех!");
});
promise.then((result) => console.log(result));
console.log("Код завершён");
✅ Ответ
Если возникли трудности, читай про эту тему здесь:
https://learn.javanoscript.ru/promise-basics
Промисы — мощная вещь, главное понять, как они работают. Ты справишься! 🚀
#javanoscript #собеседования
⚡ Задача дня
❓ Что выведет этот код?
✅ Ответ
15
Если возникли трудности, читай про эту тему здесь:
https://learn.javanoscript.ru/array-methods#reduce-reduceright
#javanoscript #собеседования
❓ Что выведет этот код?
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, curr) => acc + curr, 0);
console.log(sum);
✅ Ответ
Если возникли трудности, читай про эту тему здесь:
https://learn.javanoscript.ru/array-methods#reduce-reduceright
#javanoscript #собеседования
⚡ Задача дня
❓ Что выведет этот код?
✅ Ответ
Деление на ноль!
Операция завершена
Если возникли трудности, читай про эту тему здесь:
https://learn.javanoscript.ru/try-catch
Ошибки — это не страшно, если знаешь, как с ними справляться! 💪✨
#javanoscript #собеседования
❓ Что выведет этот код?
try {
const num = 10 / 0;
if (!isFinite(num)) {
throw new Error("Деление на ноль!");
}
} catch (error) {
console.log(error.message);
} finally {
console.log("Операция завершена");
}
✅ Ответ
Если возникли трудности, читай про эту тему здесь:
https://learn.javanoscript.ru/try-catch
Ошибки — это не страшно, если знаешь, как с ними справляться! 💪✨
#javanoscript #собеседования
Самые полезные операторы TypeScript: typeof и keyof
TypeScript даёт нам два классных оператора, которые делают работу с типами удобнее:
🔹 typeof — позволяет взять тип у уже существующей переменной:
Теперь AgeType будет всегда таким же, как тип переменной age. Это полезно, когда нужно создать новый тип на основе уже объявленных данных.
Другой пример:
Теперь UserType — это { name: string; age: number }, и если user изменится, тип автоматически обновится.
🔹 keyof — даёт список ключей объекта в виде строкового типа:
Теперь UserKeys — это "name" | "age", и мы можем использовать это, например, в функции:
Это помогает избежать ошибок, если случайно передать неправильное имя ключа.
Итог:
typeof помогает взять существующий тип.
keyof позволяет получить список ключей объекта.
Простые, но мощные штуки, которые делают код более надёжным! 🚀
TypeScript даёт нам два классных оператора, которые делают работу с типами удобнее:
🔹 typeof — позволяет взять тип у уже существующей переменной:
const age = 30;
type AgeType = typeof age; // number
Теперь AgeType будет всегда таким же, как тип переменной age. Это полезно, когда нужно создать новый тип на основе уже объявленных данных.
Другой пример:
onst user = {
name: "Alice",
age: 25,
};
type UserType = typeof user;
Теперь UserType — это { name: string; age: number }, и если user изменится, тип автоматически обновится.
🔹 keyof — даёт список ключей объекта в виде строкового типа:
type UserKeys = keyof UserType; // "name" | "age"
Теперь UserKeys — это "name" | "age", и мы можем использовать это, например, в функции:
function printUserInfo(key: UserKeys) {
console.log(key);
}
printUserInfo("name"); // ✅ Работает
// printUserInfo("email"); // ❌ Ошибка, такого ключа нет
Это помогает избежать ошибок, если случайно передать неправильное имя ключа.
Итог:
typeof помогает взять существующий тип.
keyof позволяет получить список ключей объекта.
Простые, но мощные штуки, которые делают код более надёжным! 🚀
⚡ Задача дня
Вот код:
❓ Какой тип будет у переменной key?
✅ Ответ
"id" | "name" | "isAdmin"
Если возникли трудности, можно почитать тут:
🔗 https://www.typenoscriptlang.org/docs/handbook/2/keyof-types.html
🔗 https://www.typenoscriptlang.org/docs/handbook/2/typeof-types.html
Вот код:
const user = {
id: 1,
name: "Alice",
isAdmin: true,
};
type UserKeys = keyof typeof user;
let key: UserKeys;
❓ Какой тип будет у переменной key?
✅ Ответ
Если возникли трудности, можно почитать тут:
🔗 https://www.typenoscriptlang.org/docs/handbook/2/keyof-types.html
🔗 https://www.typenoscriptlang.org/docs/handbook/2/typeof-types.html
This media is not supported in your browser
VIEW IN TELEGRAM
Кто сказал, что фастфуд только вредит?!
А если так?)
А если так?)
⚡ Задача дня
❓ Что выведет в консоль этот код?
✅ Ответ
Начало
Конец
Успех
Финально
Следующий then
💡 Запутался? Почитай подробнее про finally:
👉 https://learn.javanoscript.ru/promise-chaining
❓ Что выведет в консоль этот код?
const promise = new Promise((resolve, reject) => {
console.log("Начало");
resolve("Успех");
});
promise
.then((result) => {
console.log(result);
return "Следующий then";
})
.finally(() => {
console.log("Финально");
})
.then((data) => {
console.log(data);
});
console.log("Конец");
✅ Ответ
💡 Запутался? Почитай подробнее про finally:
👉 https://learn.javanoscript.ru/promise-chaining
❤1
⚡ Задача дня
❓ Что выведет консоль?
✅ Ответ
[undefined, 4, undefined, 8, undefined]
📚 Почитать про map можно здесь:
https://learn.javanoscript.ru/array-methods#map
❓ Что выведет консоль?
const numbers = [1, 2, 3, 4, 5];
const result = numbers.map(num => {
if (num % 2 === 0) {
return num * 2;
}
});
console.log(result);
✅ Ответ
📚 Почитать про map можно здесь:
https://learn.javanoscript.ru/array-methods#map
Принципы программирования
Чтобы писать нормальный код, который легко читать, поддерживать и расширять, нужно знать несколько ключевых принципов:
DRY (Don't Repeat Yourself — Не повторяйся)
Не дублируй код, где можно вынести в общую функцию, модуль или переменную. Чем меньше повторов, тем проще вносить изменения и понимать, что вообще происходит.
KISS (Keep It Simple, Stupid — Не усложняй)
Чем проще код, тем лучше. Если можно сделать что-то понятнее и короче — делай. Не надо усложнять без причины.
Разделяй обязанности (Separation of Concerns, SoC)
Код должен быть разбит на логические куски, каждый из которых отвечает за свою задачу.
Принцип единственной ответственности (SRP)
Каждый модуль, класс или функция должны заниматься чем-то одним. Чем меньше у них причин меняться, тем проще их тестировать и обновлять.
Открыто для расширения, закрыто для модификации (OCP)
Не трогай старый код, если можно добавить что-то новое без его изменения. Для этого есть наследование, интерфейсы и прочие штуки.
Закон Деметры (LoD) — принцип "меньше знаешь, крепче спишь"
Модули (или объекты) не должны лезть внутрь друг друга. Пусть взаимодействуют только по предоставленному API.
Не оптимизируй раньше времени
Пиши понятный код, а потом уже думай о скорости. Оптимизация ради оптимизации только запутает всех, включая тебя самого через месяц.
Пиши так, будто твой код будут читать другие
Даже если пишешь для себя, через пару месяцев ты уже не вспомнишь, что там было. Так что называй переменные понятно, добавляй комментарии и не превращай код в ребус.
Разработка через тестирование (TDD)
Сначала пиши тесты, потом код. Так ты точно будешь знать, что все работает как надо, и рефакторить код будет проще.
YAGNI (You Aren’t Gonna Need It — Тебе это не понадобится)
Не пиши функционал, который может пригодиться в будущем. Скорее всего, он не пригодится, а вот код засорит.
Соблюдая эти принципы, можно писать чистый, удобный и понятный код, который не стыдно показать коллегам. 🚀
Чтобы писать нормальный код, который легко читать, поддерживать и расширять, нужно знать несколько ключевых принципов:
DRY (Don't Repeat Yourself — Не повторяйся)
Не дублируй код, где можно вынести в общую функцию, модуль или переменную. Чем меньше повторов, тем проще вносить изменения и понимать, что вообще происходит.
KISS (Keep It Simple, Stupid — Не усложняй)
Чем проще код, тем лучше. Если можно сделать что-то понятнее и короче — делай. Не надо усложнять без причины.
Разделяй обязанности (Separation of Concerns, SoC)
Код должен быть разбит на логические куски, каждый из которых отвечает за свою задачу.
Принцип единственной ответственности (SRP)
Каждый модуль, класс или функция должны заниматься чем-то одним. Чем меньше у них причин меняться, тем проще их тестировать и обновлять.
Открыто для расширения, закрыто для модификации (OCP)
Не трогай старый код, если можно добавить что-то новое без его изменения. Для этого есть наследование, интерфейсы и прочие штуки.
Закон Деметры (LoD) — принцип "меньше знаешь, крепче спишь"
Модули (или объекты) не должны лезть внутрь друг друга. Пусть взаимодействуют только по предоставленному API.
Не оптимизируй раньше времени
Пиши понятный код, а потом уже думай о скорости. Оптимизация ради оптимизации только запутает всех, включая тебя самого через месяц.
Пиши так, будто твой код будут читать другие
Даже если пишешь для себя, через пару месяцев ты уже не вспомнишь, что там было. Так что называй переменные понятно, добавляй комментарии и не превращай код в ребус.
Разработка через тестирование (TDD)
Сначала пиши тесты, потом код. Так ты точно будешь знать, что все работает как надо, и рефакторить код будет проще.
YAGNI (You Aren’t Gonna Need It — Тебе это не понадобится)
Не пиши функционал, который может пригодиться в будущем. Скорее всего, он не пригодится, а вот код засорит.
Соблюдая эти принципы, можно писать чистый, удобный и понятный код, который не стыдно показать коллегам. 🚀
⚡ Задача дня
❓ Что выведет в консоль следующий код?
✅ Ответ
2
null
3
0
"Привет"
Если возникли трудности, можно почитать про логические операторы и оператор нулевого слияния тут:
🔗 https://learn.javanoscript.ru/logical-operators
🔗 https://learn.javanoscript.ru/nullish-operators
❓ Что выведет в консоль следующий код?
console.log(null || 2 || undefined);
console.log(1 && null && 3);
console.log(!1 || 2 && 3);
console.log(0 ?? 5);
console.log(null ?? 'Привет');
✅ Ответ
Если возникли трудности, можно почитать про логические операторы и оператор нулевого слияния тут:
🔗 https://learn.javanoscript.ru/logical-operators
🔗 https://learn.javanoscript.ru/nullish-operators
⚡ Задача дня
❓ Что выведет в консоль этот код?
💡 Запутался? Почитай подробнее про async/await и обработку ошибок:
👉 https://learn.javanoscript.ru/async-await
❓ Что выведет в консоль этот код?
async function foo() {
try {
return await Promise.reject("Ошибка!");
} catch (error) {
console.log("Ошибка поймана:", error);
}
}
foo().then((res) => console.log("Результат:", res));
💡 Запутался? Почитай подробнее про async/await и обработку ошибок:
👉 https://learn.javanoscript.ru/async-await
⚡ Задача дня
❓ Что выведет в консоль следующий код?
✅ Ответ
1 2
15 25
Если возникли трудности, можно почитать про оператор нулевого слияния и присваивание через ??= тут:
🔗 https://learn.javanoscript.ru/nullish-operators#operator-nulevogo-prisvaivaniya
❓ Что выведет в консоль следующий код?
let a = 1;
let b = 2;
a ??= 10;
b ??= 20;
console.log(a, b);
let c = null;
let d = undefined;
c ??= 15;
d ??= 25;
console.log(c, d);
✅ Ответ
Если возникли трудности, можно почитать про оператор нулевого слияния и присваивание через ??= тут:
🔗 https://learn.javanoscript.ru/nullish-operators#operator-nulevogo-prisvaivaniya
⚡ Задача дня
❓ Что выведет консоль?
✅ Ответ
[15, 20]
📚 Почитать про reduce можно здесь:
https://learn.javanoscript.ru/array-methods#reduce-reduceright
❓ Что выведет консоль?
const arr = [10, 20, 30, 40];
const result = arr.reduce((acc, num) => {
if (num > 20) {
acc.push(num / 2);
}
return acc;
}, []);
console.log(result);
✅ Ответ
📚 Почитать про reduce можно здесь:
https://learn.javanoscript.ru/array-methods#reduce-reduceright
⚡ Задача дня
Привет! Давай немного прокачаем мозги перед работой. Сегодня у нас задачка на проверку класса через instanceof.
❓ Что выведет консоль и почему?
✅ Ответ
true
true
true
false
Если что-то неясно, вот статья, которая поможет разобраться:
🔗 https://learn.javanoscript.ru/instanceof
Делись своим ответом в комментариях! 🚀
Привет! Давай немного прокачаем мозги перед работой. Сегодня у нас задачка на проверку класса через instanceof.
❓ Что выведет консоль и почему?
class Animal {}
class Dog extends Animal {}
const dog = new Dog();
console.log(dog instanceof Dog);
console.log(dog instanceof Animal);
console.log(dog instanceof Object);
console.log(dog instanceof Array);
✅ Ответ
Если что-то неясно, вот статья, которая поможет разобраться:
🔗 https://learn.javanoscript.ru/instanceof
Делись своим ответом в комментариях! 🚀
⚡ Задача дня
Привет, друг! Сегодня разберём наследование классов. Готов?
❓ Что выведет консоль и почему?
✅ Ответ
"Гав-гав!"
"Шарик"
Если хочешь разобраться глубже, вот полезная статья:
🔗 https://learn.javanoscript.ru/class-inheritance
Жду твои мысли в комментариях! 🚀
Привет, друг! Сегодня разберём наследование классов. Готов?
❓ Что выведет консоль и почему?
class Animal {
constructor(name) {
this.name = name;
}
speak() {
return `${this.name} издаёт звук.`;
}
}
class Dog extends Animal {
speak() {
return "Гав-гав!";
}
}
const dog = new Dog("Шарик");
console.log(dog.speak());
console.log(dog.name);
✅ Ответ
Если хочешь разобраться глубже, вот полезная статья:
🔗 https://learn.javanoscript.ru/class-inheritance
Жду твои мысли в комментариях! 🚀
Как я впиливала стейт-менеджер и почему это спасло проект
Это, наверное, мой самый большой Pull Request за всё время работы, и он стал идеальным подтверждением того, что стейт-менеджер может очень сильно упростить жизнь и сократить количество кода.
До этого состояние в проекте хранилось через хуки. Сначала это не вызывало проблем – всё было относительно чисто и понятно. Но со временем непредвиденные изменения в бизнес-логике, помноженные на классическое "Это нужно на проде вчера", превратили код в хаос.
Лифтинг стейта вызывал боль, передача пропсов по десятку компонентов вниз выглядела ужасно и раздувала код, а логика распространения данных стала абсолютно непрозрачной.
Настал момент, когда пересмотреть архитектуру стало неизбежно, и я взялась за рефакторинг всего проекта с внедрением стейт-менеджера. Это был непростой, но очень ценный опыт.
Итог:
✅ Чистая и предсказуемая структура хранения данных
✅ Упрощённые связи между компонентами
✅ Минимум лишнего кода
✅ Гораздо меньше боли при внесении изменений
Вывод: если проект начинает разрастаться, стейт-менеджер – не просто удобство, а необходимость. Лучше внедрить его заранее, чем потом раскапывать горы запутанного кода.
Это, наверное, мой самый большой Pull Request за всё время работы, и он стал идеальным подтверждением того, что стейт-менеджер может очень сильно упростить жизнь и сократить количество кода.
До этого состояние в проекте хранилось через хуки. Сначала это не вызывало проблем – всё было относительно чисто и понятно. Но со временем непредвиденные изменения в бизнес-логике, помноженные на классическое "Это нужно на проде вчера", превратили код в хаос.
Лифтинг стейта вызывал боль, передача пропсов по десятку компонентов вниз выглядела ужасно и раздувала код, а логика распространения данных стала абсолютно непрозрачной.
Настал момент, когда пересмотреть архитектуру стало неизбежно, и я взялась за рефакторинг всего проекта с внедрением стейт-менеджера. Это был непростой, но очень ценный опыт.
Итог:
✅ Чистая и предсказуемая структура хранения данных
✅ Упрощённые связи между компонентами
✅ Минимум лишнего кода
✅ Гораздо меньше боли при внесении изменений
Вывод: если проект начинает разрастаться, стейт-менеджер – не просто удобство, а необходимость. Лучше внедрить его заранее, чем потом раскапывать горы запутанного кода.
🔥1
⚡ Задача дня
В этом коде есть проблема с производительностью.
❓Как можно его оптимизировать?
✅ Ответ
expensiveCalculation(count) вызывается при каждом ререндере, даже если count не менялся. Нужно мемоизировать его с помощью useMemo: const result = useMemo(() => expensiveCalculation(count), [count]);.
Если возникли сложности, почитай про useMemo и оптимизацию вычислений здесь:
👉 https://ru.react.dev/reference/react/useMemo
В этом коде есть проблема с производительностью.
❓Как можно его оптимизировать?
import React, { useState } from "react";
function App() {
const [count, setCount] = useState(0);
const [text, setText] = useState("");
function increment() {
setCount(count + 1);
}
function handleChange(event) {
setText(event.target.value);
}
function expensiveCalculation(num) {
console.log("Выполняем тяжелый расчет...");
return num * 2;
}
const result = expensiveCalculation(count);
return (
<div>
<p>Результат: {result}</p>
<button onClick={increment}>+</button>
<input type="text" value={text} onChange={handleChange} />
</div>
);
}
export default App;
✅ Ответ
Если возникли сложности, почитай про useMemo и оптимизацию вычислений здесь:
👉 https://ru.react.dev/reference/react/useMemo
Please open Telegram to view this post
VIEW IN TELEGRAM
YouTube
88 LeetCode: Разбираем задачи на Javanoscript для собеседований
Задача о слиянии отсортированных массивов c LeetCode (Top Interview 150 - Merge Sorted Array):
https://leetcode.com/problems/merge-sorted-array
💡 Готовишься к собеседованию на Frontend-разработчика? В этом видео разберем популярные задачи с LeetCode, которые…
https://leetcode.com/problems/merge-sorted-array
💡 Готовишься к собеседованию на Frontend-разработчика? В этом видео разберем популярные задачи с LeetCode, которые…
Context API vs State Manager: Когда что использовать? 🤔
В React управление состоянием можно реализовать разными способами, и один из частых вопросов — когда хватит Context API, а когда нужен полноценный стейт-менеджер? Давай разберёмся!
🔡 ontext API
Context API — это встроенный инструмент React для передачи данных на глубоком уровне вложенности без проброса пропсов.
✅ Когда использовать:
- Простые глобальные состояния (тема, язык, авторизация).
- Данные, которые редко изменяются.
- Небольшие проекты, где дополнительный стейт-менеджер не оправдан.
❌ Минусы Context API:
- Ререндеры: Любое изменение контекста вызывает перерисовку всех потребителей.
- Сложность обновления: Контекст не подходит для часто меняющегося состояния, например, списка товаров в корзине.
🔡 tate Manager (Redux, Zustand, Recoil и др.)
Стейт-менеджеры предлагают централизованное хранилище, оптимизированное для обновления состояния.
✅ Когда использовать:
- Большие и сложные приложения с разными источниками состояния.
- Часто изменяемые данные (например, корзина товаров, фильтры, кэш запросов).
- Нужно разделение логики обновления и UI (например, при использовании middleware).
⚡️ Плюсы стейт-менеджеров:
- Оптимизированные обновления (Redux использует селекторы и мемоизацию, Zustand обновляет только затронутые компоненты).
- Гибкость и масштабируемость (можно легко расширять логику, добавлять middleware и асинхронные экшены).
Что выбрать?
Если нужно просто передавать тему, язык или настройки — Context API.
Если требуется сложная логика обновления, кеширование или масштабируемость — State Manager.
В React управление состоянием можно реализовать разными способами, и один из частых вопросов — когда хватит Context API, а когда нужен полноценный стейт-менеджер? Давай разберёмся!
Context API — это встроенный инструмент React для передачи данных на глубоком уровне вложенности без проброса пропсов.
- Простые глобальные состояния (тема, язык, авторизация).
- Данные, которые редко изменяются.
- Небольшие проекты, где дополнительный стейт-менеджер не оправдан.
- Ререндеры: Любое изменение контекста вызывает перерисовку всех потребителей.
- Сложность обновления: Контекст не подходит для часто меняющегося состояния, например, списка товаров в корзине.
Стейт-менеджеры предлагают централизованное хранилище, оптимизированное для обновления состояния.
- Большие и сложные приложения с разными источниками состояния.
- Часто изменяемые данные (например, корзина товаров, фильтры, кэш запросов).
- Нужно разделение логики обновления и UI (например, при использовании middleware).
- Оптимизированные обновления (Redux использует селекторы и мемоизацию, Zustand обновляет только затронутые компоненты).
- Гибкость и масштабируемость (можно легко расширять логику, добавлять middleware и асинхронные экшены).
Что выбрать?
Если нужно просто передавать тему, язык или настройки — Context API.
Если требуется сложная логика обновления, кеширование или масштабируемость — State Manager.
Please open Telegram to view this post
VIEW IN TELEGRAM
⚡ Задача дня
❓ Какой тип будет у переменной result?
✅ Ответ
{ name: string; age: number; }
Если возникли трудности, читай про эту тему здесь:
https://www.typenoscriptlang.org/docs/handbook/2/generics.html
Дженерики + объединение типов = мощь! 🚀 Используй и пиши гибкий код! 🔥
❓ Какой тип будет у переменной result?
function merge<T, U>(obj1: T, obj2: U): T & U {
return { ...obj1, ...obj2 };
}
const result = merge({ name: "Анна" }, { age: 25 });
console.log(result);
✅ Ответ
Если возникли трудности, читай про эту тему здесь:
https://www.typenoscriptlang.org/docs/handbook/2/generics.html
Дженерики + объединение типов = мощь! 🚀 Используй и пиши гибкий код! 🔥
www.typenoscriptlang.org
Documentation - Generics
Types which take parameters