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

Автор: @energy_it

Реклама на бирже:
https://telega.in/c/javascript_readyy
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
👍 JavaScript Questions — систематизированная база вопросов и разборов по ключевым концепциям!

Репозиторий представляет собой сборник вопросов с объяснениями: области видимости, замыкания, прототипное наследование, типы данных и особенности работы движка. Материал особенно полезен для подготовки к собеседованиям, повторения базовых принципов и укрепления фундаментальных знаний для разработки.

Оставляю ссылочку: GitHub 📱


📣 JS Ready | #репозиторий
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥149👍8
Свой EventEmitter на чистом JS

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

Начнём с каркаса класса:
class Emitter {
constructor() {
this.events = new Map();
}
}


Map хранит пары: имя события -> множество обработчиков.
Set удобен тем, что не допускает дубликатов и быстро удаляет функции.

Теперь метод подписки on.

Сначала достаём список обработчиков для события (или создаём новый):
on(event, handler) {
if (!this.events.has(event)) {
this.events.set(event, new Set());
}
}


Теперь добавляем обработчик:
  this.events.get(event).add(handler);
return this;
}


return this чтобы можно было делать цепочки вызовов.

Добавим emit запуск события.

Сначала берём подписчиков:
emit(event, ...args) {
const handlers = this.events.get(event);
if (!handlers) return false;
}


Если никто не подписан просто выходим.

Вызываем всех обработчиков:
  for (const handler of handlers) {
handler(...args);
}
return true;
}


args позволяет передавать любые данные в обработчики.

Теперь off отписка.

Берём подписчиков:
off(event, handler) {
const handlers = this.events.get(event);
if (!handlers) return this;
}


Удаляем конкретный обработчик:
  handlers.delete(handler);
if (handlers.size === 0) this.events.delete(event);
return this;
}


Если после удаления список пустой убираем событие полностью, чтобы не захламлять память.

Создаём обёртку, которая сама себя снимет:
once(event, handler) {
const wrap = (...args) => {
this.off(event, wrap);
handler(...args);
};


И подписываем:
  this.on(event, wrap);
return this;
}

Итог: свой EventEmitter это важно для архитектуры. Он помогает выстроить события внутри приложения без жёстких связей между модулями и делает код заметно чище.

📣 JS Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
12👍6🔥5
📂 Напоминалка по работе с массивами в JavaScript!

Например, map() позволяет преобразовать каждый элемент массива, filter() — отфильтровать данные по условию, а slice() — получить часть массива без изменения исходного.

На картинке — основные методы массивов, которые помогают работать с данными быстрее и писать чистый код.

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

📣 JS Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👍9🤝72
ResizeObserver — отслеживание изменения размеров элементов!

ResizeObserver — нативный Web API для отслеживания изменения размеров DOM-элементов. Позволяет реагировать на пересчёт layout без window.resize, опроса размеров и сторонних библиотек.

Особенно полезен для адаптивных компонентов, canvas, виртуализации и сложных UI, где размер элемента меняется независимо от окна.

Создаём наблюдатель:
const observer = new ResizeObserver(entries => {
entries.forEach(entry => {
console.log(entry.contentRect.width, entry.contentRect.height);
});
});


Колбэк вызывается после пересчёта layout в отдельной фазе доставки уведомлений (обычно до этапа отрисовки). Уведомления могут батчиться браузером.

Если внутри колбэка менять размеры наблюдаемого элемента, можно получить предупреждение: ResizeObserver loop limit exceeded или ResizeObserver loop completed with undelivered notifications. Это защита от бесконечных циклов перерасчёта.

Пример 1 — отслеживание размера элемента:
const box = document.querySelector('.box');

observer.observe(box);


entry.contentRect содержит размеры content box — области содержимого без padding, border и margin.

Для более точных измерений лучше использовать contentBoxSize или borderBoxSize.

Пример 2 — адаптация UI под ширину контейнера:
const container = document.querySelector('.container');

const responsiveObserver = new ResizeObserver(entries => {
const { width } = entries[0].contentRect;

if (width < 500) {
container.classList.add('compact');
} else {
container.classList.remove('compact');
}
});

responsiveObserver.observe(container);


Подходит для container-based адаптивности, когда поведение зависит от размера контейнера, а не viewport. (Для чисто стилевых задач также можно использовать CSS Container Queries.)

Пример 3 — работа с несколькими элементами:
document.querySelectorAll('.widget')
.forEach(el => observer.observe(el));


Один ResizeObserver может отслеживать любое количество элементов — браузер оптимизирует доставку уведомлений.

Пример 4 — точные размеры через borderBoxSize:
const preciseObserver = new ResizeObserver(entries => {
for (const entry of entries) {
const size = Array.isArray(entry.borderBoxSize)
? entry.borderBoxSize[0]
: entry.borderBoxSize;

console.log(size.inlineSize, size.blockSize);
}
});


borderBoxSize учитывает padding и border (аналог box-модели border-box). В современных браузерах поддержка хорошая, но исторически API различался, поэтому часто делают фоллбек на contentRect.

Пример 5 — прекращение наблюдения:
observer.unobserve(box);   // перестать следить за конкретным элементом
observer.disconnect(); // отключить наблюдатель полностью


Важно отключать наблюдение для удалённых элементов, чтобы избежать лишних ссылок и потенциальных утечек памяти.

🔥 ResizeObserver — базовый инструмент для построения адаптивных компонентов, реагирующих на реальные размеры контейнера, а не только на размер окна.

📣 JS Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
12👍9🤝8
This media is not supported in your browser
VIEW IN TELEGRAM
💅 Modern JS Cheatsheet — шпаргалка по JS для реальных проектов!

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

Оставляю ссылочку: GitHub 📱


📣 JS Ready | #репозиторий
Please open Telegram to view this post
VIEW IN TELEGRAM
12👍9🔥8🤝3
Объединение и клонирование объектов!

Иногда нужно объединить несколько объектов или создать копию объекта. Многие делают это вручную, добавляя свойства по одному:
const result = {};
result.id = user.id;
result.name = details.name;


В JS для этого есть нативный метод Object.assign(), который копирует собственные перечисляемые свойства из одного или нескольких объектов в целевой объект:
Object.assign(target, ...sources)


Если передать несколько источников, все их свойства будут объединены:
const merged = Object.assign({}, user, details);


Первый аргумент — объект, в который происходит копирование.

Часто передают пустой {}, чтобы получить новый объект и не изменять исходные данные:
const clone = Object.assign({}, user);


Теперь clone — поверхностная (shallow) копия объекта.

🔥 Этот метод особенно полезен при работе с конфигурациями, состоянием приложений, объединением данных API и созданием копий объектов без ручного копирования.

📣 JS Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍128🔥7🤝2
This media is not supported in your browser
VIEW IN TELEGRAM
👩‍💻 Удобное редактирование Markdown-файлов!

Markdown All in One расширяет возможности работы с Markdown в VS Code: автодополнение, быстрые команды форматирования, создание оглавления, предпросмотр, горячие клавиши и удобная навигация по документу. Всё, что нужно для комфортной работы с документацией и заметками.

📣 JS Ready | #vscode
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥97🤝1
parseInt и map — скрытая ловушка из-за второго аргумента!

Конструкция array.map(parseInt) выглядит логично, но часто даёт неожиданный результат. Всё из-за сигнатуры функции parseInt(string, radix).

Метод map передаёт в колбэк три аргумента: (element, index, array). Второй аргумент индекс — попадает в parseInt как основание системы счисления (radix).
["10", "10", "10"].map(parseInt);
// [10, NaN, 2]


Что происходит на самом деле:
parseInt("10", 0); // 10  (основание определяется автоматически)
parseInt("10", 1); // NaN (radix < 2 — недопустимо)
parseInt("10", 2); // 2 (двоичная система)


То есть результат начинает зависеть от индекса элемента. Это может привести к ошибкам при обработке данных из API, CSV, query-параметров и любых строковых чисел.

Правильный вариант — явно задать функцию преобразования:
["10", "10", "10"].map(x => parseInt(x, 10));
// [10, 10, 10]


Или использовать Number, если нужно преобразовать строку целиком:
["10", "10", "10"].map(Number);
// [10, 10, 10]


Разница между Number и parseInt существенная:
Number("10px");   // NaN
parseInt("10px"); // 10


parseInt читает число до первого нечислового символа и отбрасывает дробную часть:
parseInt("1.5"); // 1


Если нужны корректные дробные значения — лучше Number или parseFloat:
["1.5", "2.7"].map(Number);
// [1.5, 2.7]


Ещё один компактный вариант — унарный плюс:
["10", "20", "30"].map(x => +x);
// [10, 20, 30]


Он выполняет то же преобразование, что и Number, но короче.

🔥 Не передавайте parseInt напрямую в map. Всегда указывайте radix или используйте Number — так вы избежите неочевидных багов.

📣 JS Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
13🔥10👍7🤝1
Нативная группировка данных в JS!

Частая задача — сгруппировать данные по какому-то полю. Обычно это делают через reduce:
const byId = users.reduce((acc, u) => {
(acc[u.id] ??= []).push(u);
return acc;
}, {});


Но в современном JS есть нативный способ группировки — Object.groupBy():
Object.groupBy(iterable, callback)


Метод принимает итерируемую коллекцию и функцию, которая возвращает ключ группы:
const byId = Object.groupBy(users, u => u.id);


Результат — объект, где ключи это группы, а значения — массивы элементов:
{
"1": [{ id: 1, name: 'Jane' }],
"2": [{ id: 2, name: 'John' }]
}


Ключи в Object.groupBy() становятся свойствами объекта.

Если нужны ключи любого типа без преобразования — можно использовать Map.groupBy():
const grouped = Map.groupBy(users, u => u.id);


🔥 Это упрощает агрегацию данных: аналитика, таблицы, API-ответы, группировка логов, отчёты и подготовку данных для UI.

📣 JS Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥169👍9
This media is not supported in your browser
VIEW IN TELEGRAM
😎 JavaScript Algorithms — это большая коллекция алгоритмов и структур данных на чистом JS!

От сортировок, поиска и рекурсии до графов, динамического программирования и даже криптографии - всё собрано в одном месте. Каждый алгоритм снабжён кодом и пояснениями, так что учиться и разбираться просто и интересно.

Оставляю ссылочку: GitHub 📱


📣JS Ready | #репозиторий
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥148👍8👎1
📱 Работа с регулярными выражениями!

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

📣 JS Ready | #шпора
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥14🤝8👍73
📂 Напоминалка по сетевым портам!

Например, порт 22 используется для SSH-подключений, а 443 — для защищённого HTTPS-трафика. Порты — основа любого взаимодействия между клиентом и сервером.

На картинке — 18 основных портов.

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

📣 JS Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1412🤝7🔥1
matchMedia — проверка и отслеживание media queries!

matchMedia() — Web API, позволяющий проверять и отслеживать media queries напрямую из JavaScript. Это помогает синхронизировать поведение JS-кода с CSS-адаптивностью.

Функция возвращает объект MediaQueryList, содержащий результат проверки media query.

Базовое использование:
const media = window.matchMedia('(max-width: 768px)');

console.log(media.matches);


matches — boolean, показывающий соответствует ли текущий viewport заданному media query.

Пример 1 — проверка условия:
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.body.classList.add('dark-theme');
}


Так можно адаптировать поведение интерфейса под системные настройки пользователя.

Пример 2 — отслеживание изменения media query:
const media = window.matchMedia('(max-width: 768px)');

media.addEventListener('change', e => {
console.log('mobile:', e.matches);
});


Событие change срабатывает при изменении состояния media query.

Это позволяет реагировать на изменение состояния media query без использования window.resize.

Пример 3 — адаптация логики интерфейса:
const media = window.matchMedia('(max-width: 600px)');

function updateLayout(mql) {
if (mql.matches) {
enableMobileLayout();
} else {
enableDesktopLayout();
}
}

updateLayout(media);
media.addEventListener('change', updateLayout);


Обработчик сначала вызывается вручную для установки начального состояния, затем автоматически при изменении media query.

Пример 4 — учет пользовательских настроек доступности:
const motion = window.matchMedia('(prefers-reduced-motion: reduce)');

if (motion.matches) {
disableAnimations();
}


Media queries позволяют учитывать пользовательские настройки доступности.

Пример 5 — отслеживание ориентации экрана:
const orientation = window.matchMedia('(orientation: portrait)');

orientation.addEventListener('change', e => {
console.log('portrait:', e.matches);
});


matchMedia используется для: адаптивной логики интерфейса, синхронизации JavaScript и CSS media queries, учета пользовательских настроек доступности и оптимизации поведения UI на разных устройствах.

🔥 matchMedia — удобный способ проверять и отслеживать media queries напрямую из JavaScript.

📣 Code Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
10👍10🔥7🤝2
📂 Напоминалка по объектам в JavaScript!

Например, объект помогает хранить данные в формате ключ-значение, а через dot notation, bracket notation и destructuring можно быстро получать и использовать нужные свойства.

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

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

📣 JS Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥87🤝1
Как читать элементы массива с конца через at()!

Раньше доступ к элементам с конца массива требовал ручных вычислений длины и это ухудшало читаемость кода.

Например, чтобы получить последний и предпоследний элементы, обычно писали так.

Традиционный способ:
const arr = ["a", "b", "c", "d"];

const last = arr[arr.length - 1];
const prev = arr[arr.length - 2];

console.log(last); // "d"
console.log(prev); // "c"


При сложных выражениях или частых обращениях к последним элементам такой код становится менее читаемым.

Современный метод at() позволяет обращаться к элементам массива с конца через отрицательные индексы:
const arr = ["a", "b", "c", "d"];

arr.at(-1); // "d"
arr.at(-2); // "c"


Метод также поддерживает обычные положительные индексы:
arr.at(0); // "a"
arr.at(2); // "c"


Если индекс выходит за пределы массива, метод возвращает undefined:
arr.at(100);  // undefined
arr.at(-100); // undefined


Один из практических сценариев — работа со стеком, когда нужно быстро посмотреть верхний элемент:
function peek(stack) {
return stack.at(-1);
}


Метод работает не только с массивами, но и со строками:
"hello".at(-1); // "o"


В отличие от charAt(), метод at() поддерживает отрицательные индексы.

Он также доступен для TypedArray:
const bytes = new Uint8Array([10, 20, 30]);

bytes.at(-1); // 30


🔥 Важно: at() не мутирует данные и не создаёт копий — это просто способ получить элемент по индексу. Метод поддерживается современными браузерами и современными версиями Node.js.

📣 JS Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
14👍9🔥6🤝2
This media is not supported in your browser
VIEW IN TELEGRAM
👩‍💻 Когда работаешь с YAML-конфигурациями!

YAML — расширение для VS Code, которое добавляет подсветку синтаксиса, автодополнение и проверку структуры YAML-файлов. Помогает быстрее писать конфиги для Docker, Kubernetes, GitHub Actions и других инструментов, сразу показывая ошибки и подсказки.

📣 JS Ready | #vscode
Please open Telegram to view this post
VIEW IN TELEGRAM
11🔥8👍7🤝1