🤝15🔥12👍10😁1
Деструктуризация параметров в Callback!
Когда в колбэк приходит объект, не обязательно сначала принимать его целиком, а потом вытаскивать поля:
Можно сразу распаковать нужные свойства в параметрах функции:
Это делает код короче и сразу показывает, какие данные используются внутри колбэка.
🔥 Особенно полезно в
📣 JS Ready | #совет
Когда в колбэк приходит объект, не обязательно сначала принимать его целиком, а потом вытаскивать поля:
users.forEach(user => {
console.log(user.id, user.name);
});Можно сразу распаковать нужные свойства в параметрах функции:
users.forEach(({ id, name }) => {
console.log(id, name);
});Это делает код короче и сразу показывает, какие данные используются внутри колбэка.
map, filter, reduce, обработчиках событий и работе с API-данными.Please open Telegram to view this post
VIEW IN TELEGRAM
👍20❤9🔥8🤝2👎1
This media is not supported in your browser
VIEW IN TELEGRAM
Репозиторий содержит набор заданий и учебный проект по работе с JavaScript, интерфейсами и браузерным API. Здесь последовательная практика: манипуляции с DOM, события, формы, работа с данными и построение интерактивных элементов. Отличный вариант, если хочешь попрактиковаться.
Оставляю ссылочку: GitHub📱
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥18👍9🤝8
Делаем undo / redo для состояния через стек!
Отмена и повтор действий — частый интерактивный сценарий: формы, редакторы, фильтры, админки. Реализуется через два стека:
Создаём простое состояние и кнопку изменения:
Добавляем элементы на страницу, чтобы можно было взаимодействовать с интерфейсом и видеть результат изменений:
Создаём состояние приложения — в примере это простой счётчик — и сразу отображаем его текущее значение:
Добавляем историю состояний. Будем хранить прошлые состояния в
Функция изменения состояния. Перед каждым обновлением сохраняем текущий
Изменение состояния по кнопке — просто увеличиваем счётчик на единицу:
Undo — возвращает предыдущее состояние. Текущее состояние при этом переносится в
Redo — восстанавливает состояние из стека
Основные моменты:
🔥 В итоге получаем полноценный undo/redo-механизм на чистом JavaScript без сторонних библиотек.
📣 JS Ready | #практика
Отмена и повтор действий — частый интерактивный сценарий: формы, редакторы, фильтры, админки. Реализуется через два стека:
past и future.Создаём простое состояние и кнопку изменения:
const output = document.createElement("div");
const btn = document.createElement("button");
btn.textContent = "Изменить";Добавляем элементы на страницу, чтобы можно было взаимодействовать с интерфейсом и видеть результат изменений:
document.body.append(btn, output);
Создаём состояние приложения — в примере это простой счётчик — и сразу отображаем его текущее значение:
let state = { count: 0 };
output.textContent = state.count;Добавляем историю состояний. Будем хранить прошлые состояния в
past, а состояния для возможного повтора — в future.const past = [];
const future = [];
Функция изменения состояния. Перед каждым обновлением сохраняем текущий
state в историю, затем применяем новое значение и очищаем redo-историю, потому что она больше не актуальна:function setState(next) {
past.push(structuredClone(state));
state = structuredClone(next); // чтобы избежать мутаций по ссылке
future.length = 0;
output.textContent = state.count;
}Изменение состояния по кнопке — просто увеличиваем счётчик на единицу:
btn.addEventListener("click", () => {
setState({ count: state.count + 1 });
});Undo — возвращает предыдущее состояние. Текущее состояние при этом переносится в
future, чтобы его можно было восстановить обратно:function undo() {
if (!past.length) return;
future.push(structuredClone(state));
state = past.pop();
output.textContent = state.count;
}Redo — восстанавливает состояние из стека
future и делает его текущим:function redo() {
if (!future.length) return;
past.push(structuredClone(state));
state = future.pop();
output.textContent = state.count;
}Основные моменты:
past хранит прошлые состояния, future очищается при новом изменении, structuredClone делает глубокую копию без общих ссылок, подход масштабируется (diff, лимит истории, отдельный менеджер).Please open Telegram to view this post
VIEW IN TELEGRAM
❤12👍8🤝8
Например, startsWith(), endsWith() и includes() используются для логических проверок содержимого строки, а indexOf() и lastIndexOf() — для получения позиции первого и последнего вхождения подстроки.
На изображении собраны базовые методы строкового поиска, которые покрывают большинство повседневных задач при работе с текстом и данными.
Сохраните, чтобы не забыть!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥10❤7🤝2
Значение по умолчанию при деструктуризации!
Если объект может не содержать нужных полей, необязательно писать проверки внутри функции. Значения по умолчанию можно задать прямо в деструктуризации.
Без дефолтов придётся страховаться вручную:
Проблема в том, что оператор
Корректнее задать значения по умолчанию прямо в параметрах функции. Они применяются только если свойство равно undefined:
Теперь передача неполных данных не ломает логику:
Частый кейс — безопасная обработка параметров опционального объекта. Чтобы функция не падала при вызове без аргументов, задаём дефолт всему параметру:
Теперь корректны все варианты вызова:
Подход делает сигнатуру функции самодокументируемой и избавляет от защитного кода внутри тела.
🔥 Особенно полезно в API-обёртках, утилитах, React-компонентах и обработчиках конфигурации.
📣 JS Ready | #практика
Если объект может не содержать нужных полей, необязательно писать проверки внутри функции. Значения по умолчанию можно задать прямо в деструктуризации.
Без дефолтов придётся страховаться вручную:
function printUser(user) {
const name = user.name || "Unknown";
const age = user.age || 0;
console.log(name, age);
}Проблема в том, что оператор
|| подменяет любые falsy-значения — пустую строку, 0 или false, даже если они валидны.Корректнее задать значения по умолчанию прямо в параметрах функции. Они применяются только если свойство равно undefined:
function printUser({ name = "Unknown", age = 0 }) {
console.log(name, age);
}Теперь передача неполных данных не ломает логику:
printUser({ name: "Alex" }); // Alex 0
printUser({ age: 25 }); // Unknown 25
printUser({}); // Unknown 0Частый кейс — безопасная обработка параметров опционального объекта. Чтобы функция не падала при вызове без аргументов, задаём дефолт всему параметру:
function createUser({ name = "Guest", role = "user" } = {}) {
return { name, role };
}Теперь корректны все варианты вызова:
createUser({ name: "Mira" });
createUser({});
createUser();Подход делает сигнатуру функции самодокументируемой и избавляет от защитного кода внутри тела.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18❤9🤝8
This media is not supported in your browser
VIEW IN TELEGRAM
Simple React Snippets — добавляет быстрые шаблоны для React: функциональные компоненты, импорт React, хуки, export по умолчанию и другие часто используемые конструкции. Вводишь короткое сокращение, получаешь готовый каркас компонента.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥20👍14❤9👎1
Сглаживание массивов без reduce и рекурсии!
Когда массив содержит вложенные массивы, можно не писать сложные циклы или рекурсивные функции —
Если нужно полностью полностью развернуть вложенную структуру любой глубины, можно указать
Когда требуется не просто сгладить, а сначала преобразовать элементы, используйте
🔥 Такой примем пригодится для обработки результатов API, древовидных структур, списков и любых вложенных данных.
📣 JS Ready | #совет
Когда массив содержит вложенные массивы, можно не писать сложные циклы или рекурсивные функции —
flat делает это проще:nested.flat(2); // сглаживает на глубину 2
Если нужно полностью полностью развернуть вложенную структуру любой глубины, можно указать
Infinity:nested.flat(Infinity);
Когда требуется не просто сгладить, а сначала преобразовать элементы, используйте
flatMap — он объединяет map и flat(1) в одну операцию:[1, 2, 3].flatMap(x => [x, x * 2]);
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14❤11👍10
This media is not supported in your browser
VIEW IN TELEGRAM
Структурированная программа обучения, охватывающая ключевые концепции языка: синтаксис, условные конструкции, функции и основы отладки. Материал подаётся через видеоуроки и задания, что позволяет закреплять теорию на практике и формировать базу для дальнейшего изучения веб-разработки.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤13👍10🔥9🤝1
В шпаргалке собраны основные способы работы с числовыми значениями. Рассматриваются явное приведение типов, строгие проверки корректности и конечности чисел, а также разбор строковых представлений целых и дробных значений. Материал охватывает примеры валидации, безопасной работы с целыми числами и корректного извлечения чисел из строк.Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤10🔥10
Как убрать undefined / null поля из объекта?
Частая проблема, в объекте есть пустые поля, которые ломают API-запросы, формы или сериализацию.
Получаем пары ключ-значение:
Фильтруем только реальные значения, убирая null и undefined:
Собираем обратно в объект:
🔥 Идеально перед
📣 JS Ready | #совет
Частая проблема, в объекте есть пустые поля, которые ломают API-запросы, формы или сериализацию.
Получаем пары ключ-значение:
Object.entries(obj)
Фильтруем только реальные значения, убирая null и undefined:
.filter(([, v]) => v != null)
Собираем обратно в объект:
Object.fromEntries(...)
fetch, сохранением настроек, формами и любыми динамическими параметрами, очищает данные без циклов и мутаций.Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤9🤝9
event.target и event.currentTarget — правильная работа с делегированием!В обработчиках событий часто путают два разных элемента: тот, по которому пользователь действительно кликнул, и тот, на котором висит слушатель. В DOM это разные роли, и для них существуют свойства
event.target и event.currentTarget.event.target — источник события (самый глубокий элемент):list.addEventListener("click", e => {
console.log("target:", e.target);
});
Если кликнуть по кнопке внутри списка,
target будет тем узлом, по которому пришёлся клик. Если внутри кнопки есть вложенные элементы, target может оказаться ими, а не самой кнопкой.event.currentTarget — элемент, на котором висит обработчик:list.addEventListener("click", e => {
console.log("currentTarget:", e.currentTarget);
});
Он всегда равен
list, потому что обработчик привязан именно к этому элементу, независимо от места клика внутри него.Практический пример делегирования:
document
.querySelector("#menu")
.addEventListener("click", e => {
if (e.target.matches("button")) {
console.log("Нажата кнопка:", e.target.textContent);
}
});
Если внутри кнопки есть вложенные элементы, условие может не сработать, потому что
target будет не кнопкой.Надёжнее использовать
closest():document
.querySelector("#menu")
.addEventListener("click", e => {
const btn = e.target.closest("button");
if (!btn || !e.currentTarget.contains(btn)) return;
console.log("Нажата кнопка:", btn.textContent);
});
Проверка
contains гарантирует, что найденная кнопка действительно находится внутри текущего контейнера.Когда нужен именно контейнер — используем
currentTarget:container.addEventListener("click", e => {
e.currentTarget.classList.toggle("active");
});
Класс изменится у контейнера, даже если клик был по вложенному элементу.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤13👍9🔥8
Please open Telegram to view this post
VIEW IN TELEGRAM
❤14🔥8🤝8
Event Delegation — один обработчик вместо десятков!
Частая ошибка — навешивать обработчик на каждый элемент списка. Это усложняет код, требует повторных подписок при обновлении DOM и не работает для динамически добавленных элементов. Гораздо надёжнее использовать делегирование событий — один обработчик на общем родителе.
Обработчик на каждый элемент:
Такой подход не масштабируется: новые элементы остаются без обработки, а при повторной инициализации легко получить дубли подписок.
Делегирование через родителя:
События в DOM всплывают вверх по дереву (bubbling), поэтому родитель может перехватить клик. Через
Работает с динамическими элементами:
Новый элемент автоматически обрабатывается существующим обработчиком — дополнительных подписок не требуется.
🔥 Подход не применим к событиям без всплытия (например,
📣 Code Ready | #практика
Частая ошибка — навешивать обработчик на каждый элемент списка. Это усложняет код, требует повторных подписок при обновлении DOM и не работает для динамически добавленных элементов. Гораздо надёжнее использовать делегирование событий — один обработчик на общем родителе.
Обработчик на каждый элемент:
document.querySelectorAll('.list .item button').forEach(btn => {
btn.addEventListener('click', () => {
console.log('Clicked:', btn.dataset.id);
});
});Такой подход не масштабируется: новые элементы остаются без обработки, а при повторной инициализации легко получить дубли подписок.
Делегирование через родителя:
const list = document.querySelector('.list');
list.addEventListener('click', (e) => {
const button = e.target.closest('button');
if (!button || !list.contains(button)) return;
console.log('Clicked:', button.dataset.id);
});События в DOM всплывают вверх по дереву (bubbling), поэтому родитель может перехватить клик. Через
closest() мы определяем фактический источник действия, даже если клик был по вложенному элементу внутри кнопки.Работает с динамическими элементами:
list.insertAdjacentHTML('beforeend', `
<li class="item">
<button data-id="10">New item</button>
</li>
`);Новый элемент автоматически обрабатывается существующим обработчиком — дополнительных подписок не требуется.
focus, blur), может конфликтовать с точечным использованием stopPropagation() и требует осознанного выбора контейнера, чтобы не перехватывать лишние события.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10❤8👍7🤝1
This media is not supported in your browser
VIEW IN TELEGRAM
Rainbow CSV раскрашивает столбцы в разные цвета, благодаря чему данные становятся наглядными и легко читаемыми прямо в редакторе. Помогает быстро ориентироваться в таблицах, находить нужные значения и проверять корректность структуры без использования сторонних программ. Особенно полезно при работе с логами и большими наборами данных.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥9🤝7