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

Автор: @energy_it

Реклама на бирже:
https://telega.in/c/javascript_readyy
Download Telegram
📱 Определяем, кто был более разговорчивым в чате!

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

В этом посте:
Подсчитаем количество слов в каждом сообщении.

Разделим сообщения по ролям: user и bot.

Сравним итоговые показатели.

Определим, кто общался активнее.


Итоговый скрипт — простой и наглядный способ замерять активность в диалогах без использования сторонних библиотек.

📣 JS Ready | #задача
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍147🤝7🔥5
📂 Напоминалка как сгруппировать массив объектов по ключу!

Например, Object.groupBy() позволяет быстро сгруппировать элементы массива (или любого итерируемого объекта) по заданному ключу.

На картинке — простой и наглядный пример: список задач группируется по полю project, и на выходе получается объект, где ключ — это проект, а значение — массив соответствующих задач.

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

📣 JS Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1410👍8
Array.prototype.some — простой метод, который часто недоиспользуют!

В JavaScript-коде до сих пор часто встречается ручной перебор с флагами, break и лишними переменными. Хотя для многих таких проверок уже есть готовый метод — some.

Он отвечает на простой вопрос: есть ли в массиве хотя бы один элемент, который подходит под условие.
const arr = [1, 2, 3, 4];

const hasEven = arr.some(n => n % 2 === 0);

console.log(hasEven); // true


some проходит по массиву и возвращает true, как только предикат впервые вернул true. Если ни один элемент не подошёл — результат будет false.

То же самое часто пишут через for:
let hasEven = false;

for (const n of arr) {
if (n % 2 === 0) {
hasEven = true;
break;
}
}


Работает, но в большинстве случаев это лишнее состояние. Через some намерение видно сразу.

Пример с объектами:
const users = [
{ id: 1, active: false },
{ id: 2, active: true }
];

const hasActive = users.some(user => user.active);

console.log(hasActive); // true


Так удобно проверять наличие нужного состояния, флага или признака в коллекции.

Проверка ролей:
const roles = ["user", "editor"];

const canEdit = roles.some(role => role === "admin" || role === "editor");

console.log(canEdit); // true


А если список разрешённых ролей уже вынесен отдельно, можно сделать так:
const allowedRoles = ["admin", "editor"];
const roles = ["user", "editor"];

const canEdit = roles.some(role => allowedRoles.includes(role));


Валидация данных:
const inputs = ["ok", "", "valid"];

const hasEmpty = inputs.some(value => value.trim() === "");

console.log(hasEmpty); // true


Как только найдено некорректное значение, дальнейший обход прекращается.

Отличие от every:
const arr = [2, 4, 6];

arr.some(n => n > 5); // true
arr.every(n => n > 5); // false


some — хотя бы один элемент; every — все элементы.

На пустом массиве:
[].some(() => true); // false


Это ожидаемое поведение: в массиве нет ни одного элемента, который мог бы удовлетворить условию.

Важный момент — ранний выход:
arr.some(expensiveCheck);


В отличие от map или filter, метод some не обязан проходить весь массив. Если условие уже выполнено, обход сразу прекращается. Это особенно полезно, если внутри предиката есть дорогая операция.

Поэтому вместо такой цепочки:
const result = data
.filter(x => x.enabled)
.some(x => x.value > 100);


часто лучше написать так:
const result = data.some(x => x.enabled && x.value > 100);


Так массив не фильтруется заранее, не создаётся промежуточная коллекция, и проверка может завершиться раньше.

Альтернатива через find:
const exists = arr.find(x => x > 10) !== undefined;


Так тоже пишут, но если нужен только boolean-ответ, some обычно точнее выражает намерение:
const exists = arr.some(x => x > 10);


🔥 some — базовый инструмент для проверок. Когда нужно понять, есть ли в массиве хотя бы один подходящий элемент, он часто чище и понятнее ручных циклов с флагами.

📣 JS Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
14👍9🔥8🤝1
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