JavaScript Ready | Программирование
7.87K subscribers
880 photos
58 videos
435 links
Авторский канал по разработке на JavaScript.
Ресурсы, обучения, задачи, шпаргалки.
Ежедневно информация пополняется!

Автор: @energy_it

Реклама на бирже:
https://telega.in/c/javascript_readyy
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
👩‍💻 Нужно быстро привести CSV-файл к читаемому виду?

CSV to Table —
позволяет отобразить содержимое CSV как таблицу прямо в VS Code. Данные выравниваются по столбцам, становятся наглядными и удобными для анализа без открытия сторонних инструментов. Полезно при работе с выгрузками, логами и любыми табличными данными.

📣 JS Ready | #vscode
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🤝87
Деструктуризация с rest как альтернатива slice!

Когда нужно взять первый элемент и всё остальное, обычно пишут через индексы и slice:
const parts = data.split(',');
const first = parts[0];
const rest = parts.slice(1);


Получается лишний код и промежуточные переменные.

Деструктуризация решает это одной строкой:
const [first, ...rest] = data.split(',');


Первый элемент забирается отдельно, остальные автоматически собираются в массив:
first // 'a'
rest // ['b', 'c']


Работает с любыми массивами и результатами функций:
const [head, ...tail] = arr;


🔥 Часто используется в парсинге, работе со строками, аргументами функций и любом коде, где нужно разделить первое значение и остаток без лишней логики.

📣 JS Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
14👍7🤝5🔥4
This media is not supported in your browser
VIEW IN TELEGRAM
JS Challenger — сайт с короткими задачами по JavaScript — от простых до реально коварных. Отличный способ прокачаться без регистрации и лишнего UI.

📌 Оставляю ссылочку: jschallenger.com

📣 JS Ready | #сайт
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥10🤝63
📂 Напоминалка по аутентификации и сессиям!

Например, cookies используются для хранения данных на клиенте, sessions — для stateful-логики на сервере, JWT — для stateless-аутентификации, а PASETO — более безопасная альтернатива токенам.

На картинке — основные подходы: cookies, sessions, JWT и PASETO, их структура и базовые схемы работы.

Сохрани, чтобы не потерять!

📣 JS Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥7🤝73
Разбираем способ объединять отмену из нескольких источников!

Ситуация: есть async операция, и её нужно отменять по разным причинам: пользователь ушёл со страницы / компонент размонтировался, истёк таймаут, пришёл новый запрос.

Когда условий больше одного, код часто начинает разрастаться: вручную прокидываются отмены, добавляются таймауты, появляется лишняя синхронизация. Это работает, но плохо масштабируется и легко ломается.

Нативное решение — AbortSignal.any():
const controller = new AbortController();

const signal = AbortSignal.any([
controller.signal,
AbortSignal.timeout(3000)
]);


Мы просто описываем правило: отмени, если сработает любой из сигналов. Теперь операция отменится либо вручную через controller.abort(), либо по таймауту.

Использование с fetch:
try {
const res = await fetch("/api/data", { signal });
const data = await res.json();
} catch (err) {
if (signal.aborted) {
// отмена: manual abort, timeout или другой источник
return;
}

throw err;
}


Если reject не обработан — будет unhandled rejection. Поведение: если вызвать controller.abort() раньше таймаута — сработает он, если не вызывать — операция завершится по таймауту. Комбинированный сигнал абортится один раз — по первому событию.

Разбираем кейс — последний запрос побеждает + таймаут:
let controller;

async function load() {
controller?.abort();
controller = new AbortController();

const signal = AbortSignal.any([
controller.signal,
AbortSignal.timeout(5000)
]);

try {
const res = await fetch("/api", { signal });
return res.json();
} catch (err) {
if (signal.aborted) return;
throw err;
}
}


Что это даёт: старые запросы отменяются и текущий не висит бесконечно. Важно: в этом примере при отмене load() вернёт undefined, потому что мы явно делаем return в catch. Это нужно учитывать в вызывающем коде.

Комбинация с lifecycle:
function load(signalFromUI) {
const signal = AbortSignal.any([
signalFromUI,
AbortSignal.timeout(3000)
]);

return fetch("/api", { signal });
}


Ты не завязываешься на конкретный источник отмены — просто собираешь сигналы. AbortSignal.any() создаёт новый сигнал со своим lifecycle.

Причина берётся от первого сработавшего сигнала:
const controller = new AbortController();

const signal = AbortSignal.any([
controller.signal,
AbortSignal.timeout(3000)
]);

controller.abort("manual");

console.log(signal.reason); // "manual"


если abort() без аргумента, то обычно будет AbortError, если сработал AbortSignal.timeout() — будет TimeoutError, если abort("manual") — reason будет "manual".

API относительно новый. В Node: AbortSignal.timeout() есть с Node 16.14.0 / 17.3.0; AbortSignal.any() есть с Node 18.17.0 / 20.3.0

🔥 Как только появляется больше одного условия отмены — AbortSignal.any() упрощает код и убирает ручную синхронизацию.

📣 JS Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
👍117🔥7
This media is not supported in your browser
VIEW IN TELEGRAM
👩‍💻 Важно держать код предсказуемым и сразу видеть ошибки?

ESLint — это не просто подсветка ошибок, а инструмент анализа кода. Он находит потенциальные баги, антипаттерны и несоответствие правилам проекта, а также умеет автоматически исправлять часть проблем. Работает через конфиги и плагины (React, Next.js и др.), помогает держать код единообразным.

📣 JS Ready | #vscode
Please open Telegram to view this post
VIEW IN TELEGRAM
👍146🤝6
Почему объекты не равны и как их сравнить без библиотек?

В JavaScript объекты сравниваются по ссылке, а не по содержимому.
{ x: 1 } === { x: 1 } // false


Даже если структура полностью совпадает — это разные объекты.

Для простых данных можно использовать JSON.stringify.
JSON.stringify(a) === JSON.stringify(b) // true


Но важно понимать ограничения:
JSON.stringify({ a: 1, b: 2 }) === JSON.stringify({ b: 2, a: 1 })
// false (порядок ключей важен)


Также не работает с undefined, функциями, Symbol и BigInt.

🔥 Приём для тестов, простых кешей и сравнений JSON-данных.

📣 JS Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍118🔥7
📂 Напоминалка по Web Performance Metrics!

Например, TTFB показывает, как быстро сервер начинает отвечать, а FCP помогает понять, когда пользователь впервые видит контент на экране.

На картинке — 9 основных метрик производительности сайта, которые полезно держать под рукой каждому разработчику.

Сохрани, чтобы не потерять!

📣 JS Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
9👍6🤝5
Proxy — перехватываем изменения объекта!

Proxy — одна из возможностей JS, про которую многие знают только поверхностно. На практике он позволяет перехватывать чтение, запись, удаление и даже вызовы функций, превращая обычный объект в управляемую структуру данных.

Создадим объект и обернём его в Proxy:
const user = { name: "Alex" };

const proxy = new Proxy(user, {
set(target, key, value) {


Теперь любое изменение объекта можно контролировать централизованно.

Перехватываем запись значений:
console.log(` ${key} = ${value}`);    
target[key] = value;
return true; }}
);


set вызывается каждый раз при изменении свойства — это основа реактивности во многих frontend-фреймворках.

Пробуем изменить объект:
proxy.name = "John";
proxy.age = 30;

// name = John
// age = 30


Даже новые свойства автоматически проходят через обработчик.

Через Proxy удобно валидировать данные до записи:
const settings = new Proxy({}, {
set(obj, key, value) {
if (key === "port" && value > 65535)
throw Error("Некорректный порт");


Теперь объект сам защищает свои данные от невалидных значений.

Завершаем логику и тестируем:
   obj[key] = value;    
return true;
}
});

settings.port = 3000;


Такой подход часто используют в системах реактивности, конфиг-движках, ORM и инструментах разработки, где важно централизованно контролировать изменения данных.

🔥 Proxy позволяет буквально вклиниться между кодом и объектом, превращая обычные структуры данных в управляемые и расширяемые механизмы с собственной логикой поведения.

📣 JS Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥134👍4
This media is not supported in your browser
VIEW IN TELEGRAM
❤️ Dev Notes — заметки, шпаргалки и статьи по JS!

На сайте собраны не только шпаргалки, но и полноценные статьи с разбором разных тем: работа с массивами и объектами, функции, замыкания, методы JS и практические нюансы разработки. Материал подаётся с примерами кода и краткими пояснениями.

📌 Оставляю ссылочку: dev-notes.ru

📣 JS Ready | #сайт
Please open Telegram to view this post
VIEW IN TELEGRAM
15👍7🤝6
Разбираем как не словить утечку памяти на обработчиках событий!

Одна из частых причин утечек — обработчик повесили, а снять забыли. Особенно это неприятно, когда событие висит не на локальном элементе, а на чём-то долгоживущем: window, document, глобальный event bus и т.п.

function mount() {
window.addEventListener('resize', onResize);
}

function unmount() {
// забыли снять обработчик
}


Компонента уже нет, а onResize всё ещё вызывается. Плюс callback может держать в замыкании старое состояние, DOM-ноды, данные — и GC не сможет это нормально прибрать.

Правильнее сразу закладывать cleanup:

function mount() {
window.addEventListener('resize', onResize);
}

function unmount() {
window.removeEventListener('resize', onResize);
}


Главное — снимать нужно ту же самую функцию.

Вот так не сработает:

el.addEventListener('click', () => doSomething());
el.removeEventListener('click', () => doSomething());


Это две разные функции, даже если выглядят одинаково.

Нормальный вариант:

function handler() {
doSomething();
}

el.addEventListener('click', handler);
el.removeEventListener('click', handler);


Ещё момент — capture.

el.addEventListener('click', handler, true);
el.removeEventListener('click', handler, false);


Так обработчик не снимется, потому что capture отличается. Для удаления браузер сравнивает type, listener и capture.
passive, once, signal в этом сравнении не участвуют.

Когда обработчиков несколько, удобно использовать AbortController:

const controller = new AbortController();

window.addEventListener('resize', onResize, {
signal: controller.signal
});

document.addEventListener('visibilitychange', onVisible, {
signal: controller.signal
});

// cleanup
controller.abort();


abort() снимет все обработчики, которые были добавлены с этим signal.

А если обработчик нужен только один раз:

button.addEventListener('click', handler, { once: true });


После первого вызова он удалится сам. Важный нюанс: удалённый DOM сам по себе ещё не утечка. Если на него нет внешних ссылок — GC его заберёт.

🔥 Проблемы начинаются, когда: обработчик висит на window / document; callback держит старое состояние в замыкании; DOM-нода или данные лежат в массиве, store или кэше.

📣 JS Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
👍118🔥6
This media is not supported in your browser
VIEW IN TELEGRAM
👩‍💻 Хочется сразу видеть, какой цвет используется в коде?

Colorize —
подсвечивает все цветовые значения прямо в редакторе: HEX, RGB, HSL, CSS-переменные и другие форматы. Вместо набора символов ты сразу видишь реальный цвет рядом с кодом. Удобно при работе с UI, темами и большими CSS/SCSS-файлами, где важно быстро ориентироваться в палитре проекта.

📣 JS Ready | #vscode
Please open Telegram to view this post
VIEW IN TELEGRAM
10👍10🤝7
📱 Функции высшего порядка!

В этой шпаргалке собраны ключевые приёмы работы с контекстом, композициями и оптимизацией вызовов функций. Методы помогут писать чище, управлять потоком данных и улучшать производительность JS-кода.

📣 JS Ready | #шпора
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥116👍6
📂 Напоминалка по API-архитектурам и взаимодействию сервисов!

Например, REST отлично подходит для простых CRUD API, GraphQL позволяет получать только нужные данные одним запросом, а gRPC обеспечивает максимально быстрое взаимодействие между микросервисами через HTTP/2 и Protobuf.

На картинке — основные отличия REST, GraphQL и gRPC: принципы работы, структура запросов, особенности передачи данных и сценарии использования.

Сохрани, чтобы не потерять!

📣 JS Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍6🤝41
Почему await внутри forEach не работает как ожидается?

Многие думают, что await внутри forEach остановит выполнение цикла. Но forEach не работает с Promise и не ждёт завершения callback.
console.log('done'); // выполнится раньше запросов


Из-за этого легко получить гонки, неожиданный порядок выполнения и баги.

Правильный способ — for...of.
for (const id of ids) {
await fetch(`/user/${id}`);
}


Теперь каждая операция действительно ждёт предыдущую.

Если нужна параллельность — используйте Promise.all.
await Promise.all(
ids.map(id => fetch(`/user/${id}`))
);


🔥 Это одна из самых частых async-ловушек в JavaScript. Особенно полезно в API, очередях задач, миграциях и любом коде, где важен контроль выполнения.

📣 JS Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👍6🤝51
This media is not supported in your browser
VIEW IN TELEGRAM
👩‍💻 В коде слишком много операторов и условий?

Snazzy Operator — делает операторы (=>, ===, &&, >= и другие) более выразительными и аккуратными за счёт специальных лигатур и стилизации. Код становится легче воспринимать визуально, особенно в больших файлах и сложных условиях.

📣 JS Ready | #vscode
Please open Telegram to view this post
VIEW IN TELEGRAM
👍176🔥5
📂 Напоминалка по аутентификации и авторизации!

Например, Session Cookie хранит session ID на клиенте, а JWT позволяет серверу проверять пользователя без хранения сессии.

На картинке — основные подходы: WWW-Authenticate, Session Cookie, JWT, Token-based auth, SSO и OAuth 2.0 grant flows.

Сохрани, чтобы не потерять!

📣 JS Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
👍115🔥5