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

Автор: @energy_it

Реклама на бирже:
https://telega.in/c/javascript_readyy
Download Telegram
📱 Функции высшего порядка!

В этой шпаргалке собраны ключевые приёмы работы с контекстом, композициями и оптимизацией вызовов функций. Методы помогут писать чище, управлять потоком данных и улучшать производительность 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
Как искать с конца массива без reverse и лишних копий?

Когда нужен последний подходящий элемент, часто сначала разворачивают массив или пишут цикл с конца:
const lastError = [...logs].reverse().find(x => !x.ok);


В JavaScript для этого есть нативный метод findLast():
const lastError = logs.findLast(x => !x.ok);


Он проходит массив с конца и сразу возвращает первый подходящий элемент.

Ничего не копирует и не мутирует:
const lastBig = [10, 20, 30, 40].findLast(x => x > 15);
// 40


Если нужен не сам элемент, а его позиция, рядом есть findLastIndex():
const idx = logs.findLastIndex(x => !x.ok);
// 2


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

📣 JS Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🤝6🔥51
This media is not supported in your browser
VIEW IN TELEGRAM
👩‍💻 Подсветка и удобная работа с env-конфигами!

env-cmd-file-syntax — добавляет подсветку и поддержку синтаксиса для файлов env-cmd, помогая удобнее работать с переменными окружения. Расширение делает конфиги читаемее, упрощает навигацию и помогает быстрее замечать ошибки в названиях и структуре переменных.

📣 JS Ready | #vscode
Please open Telegram to view this post
VIEW IN TELEGRAM
10👍7🤝5🔥1
String.prototype.matchAll — когда нужно работать со всеми совпадениями и группами!

Обычно для поиска по строке используют match или exec, но у них есть ограничения: либо приходится писать цикл с lastIndex, либо поведение с группами зависит от режима работы.

matchAll решает это аккуратно — возвращает итератор по всем совпадениям с доступом к группам, без ручного управления состоянием.

Базовый пример:
const str = "id=1 id=2 id=3";

const matches = str.matchAll(/id=(\d+)/g);

for (const m of matches) {
console.log(m[1]);
}
// 1 2 3


На выходе — последовательность результатов, аналогичных exec: это массивы с доступом к группам, индексу и исходной строке. Разница в том, что не нужно вручную крутить цикл и следить за lastIndex.

Как ведёт себя match, здесь часто возникает путаница — match работает по-разному в зависимости от флага g:
"id=1".match(/id=(\d+)/);
// ["id=1", "1", ...]

"id=1 id=2".match(/id=(\d+)/g);
// ["id=1", "id=2"]


При глобальном поиске (g) match возвращает только полные совпадения — без capture groups. Это как раз типичный кейс, где matchAll удобнее.

Извлечение структурированных данных:
const str = "x:10 y:20 z:30";

const result = [...str.matchAll(/(\w):(\d+)/g)]
.map(([, key, val]) => [key, Number(val)]);

console.log(Object.fromEntries(result));
// { x: 10, y: 20, z: 30 }


matchAll позволяет сразу получить пары ключ–значение без ручного управления состоянием регулярки.

Работа с индексами
const str = "test1 test2";

for (const m of str.matchAll(/\w+\d/g)) {
console.log(m[0], m.index);
}
// test1 0
// test2 6


Каждое совпадение содержит позицию (index), что удобно для парсинга, подсветки, токенизации.

Важно: нужен флаг g
"abc".matchAll(/a/);
// TypeError


Если передать RegExp без g, будет ошибка. Корректно:
[..."abc".matchAll(/a/g)];


Также можно передать строку — она будет неявно преобразована в RegExp с флагом g:
[..."abcabc".matchAll("a")];


Именованные группы
const str = "2026-04-19";

for (const m of str.matchAll(
/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/g
)) {
console.log(m.groups.year);
}


Именованные группы повышают читаемость, особенно при большом количестве групп.

Отличие от exec:
const str = "id=1 id=2 id=3";
const re = /id=(\d+)/g;
let m;

while ((m = re.exec(str))) {
console.log(m[1]);
}


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

🔥 matchAll решает это: он использует внутренний клон регулярки, поэтому не мутирует исходный RegExp и не требует ручного контроля состояния.

📣 JS Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
10👍6🤝4
This media is not supported in your browser
VIEW IN TELEGRAM
💅 Josh W. Comeau — статьи и руководства по JavaScript и React!

На сайте собраны статьи и интерактивные туториалы по JavaScript, React, CSS-анимациям, Flexbox, Grid и архитектуре интерфейсов. Автор объясняет сложные концепции простым языком и показывает не только как, но и почему это работает.

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

📣 JS Ready | #сайт
Please open Telegram to view this post
VIEW IN TELEGRAM
12👍7🤝5
Почему setTimeout в Node.js и браузере возвращает разные типы?

Многие думают, что setTimeout всегда возвращает число.
const id = setTimeout(fn, 1000);


В браузере это действительно numeric id.
typeof id // 'number'


Но в Node.js возвращается объект Timeout.
typeof id // 'object'


Из-за этого часто возникают проблемы с TypeScript-типами и universal/fullstack кодом между браузером и Node.js.

Например, такой код уже не универсален:
let timerId: number;

timerId = setTimeout(fn, 1000);


Правильный универсальный тип:
let timerId: ReturnType<typeof setTimeout>;


🔥 Он автоматически подстроится под окружение.

📣 JS Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🔥8🤝52
📂 Напоминалка по методам массивов!

Например, push() добавляет элементы в конец массива, map() создаёт новый массив после преобразования, а splice() умеет удалять и вставлять элементы прямо в исходный массив.

На картинке — удобная шпаргалка по основным методам массивов: мутации, поиск, трансформация, immutable-методы ES2023 и статические методы.

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

📣 JS Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
14👍7🔥5
Почему отрицательные индексы в массиве “работают”, но не так как ожидается?

Многие думают, что arr[-1] — это доступ к последнему элементу, как в Python.
arr[-1]


Но в JavaScript массив — это обычный объект.

Отрицательный индекс не становится индексом массива, а превращается в обычное свойство объекта.
arr['-1'] = 'test'


Поэтому length вообще не меняется.
arr.length // 3


И методы массива не видят такие значения.
arr.map(x => x) // без 'test'


Для нормального доступа с конца есть специальный метод .at()
arr.at(-1)


🔥 Очень неочевидная особенность языка, которая часто всплывает при портировании кода из Python и работе с индексами.

📣 JS Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍147🔥5
This media is not supported in your browser
VIEW IN TELEGRAM
🤔 Code JavaScript — большой учебник и практикум по JS!

На сайте собрана полноценная база материалов по JavaScript: от базового синтаксиса и работы с DOM до более сложных тем вроде замыканий, событий, async/await и ООП. Материал построен в формате уроков и практических заданий, поэтому подходит не только для чтения, но и для закрепления знаний на практике.

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

📣 JS Ready | #сайт
Please open Telegram to view this post
VIEW IN TELEGRAM
🤝118👍5
Почему Object.freeze() не делает объект полностью immutable?

Object.freeze() часто воспринимают как "защитить объект от любых изменений". Но есть нюанс: он работает только поверхностно.
const config = Object.freeze({
api: { retry: 3 }
});

config.api.retry = 10;

console.log(config.api.retry);
// 10


На первый взгляд странно: объект же frozen. Но заморожен только сам config. Свойство api действительно нельзя переназначить, удалить или изменить его descriptor. А вот объект, на который оно ссылается, остаётся обычным mutable-объектом.

То есть вот так уже нельзя:
config.api = null;

console.log(config.api);
// { retry: 10 }


И тут важный момент: в обычном режиме js просто проигнорирует такую попытку; в "use strict" будет TypeError.

Пример:
"use strict";

const user = Object.freeze({
name: "Alex"
});

user.name = "John";
// TypeError: Cannot assign to read only property 'name'


Но вложенные объекты всё равно можно менять, если их отдельно не заморозить. Для базовой глубокой заморозки можно написать небольшой хэлпер:
function deepFreeze(obj) {
if (obj && typeof obj === "object" && !Object.isFrozen(obj)) {
Object.values(obj).forEach(deepFreeze);
Object.freeze(obj);
}

return obj;
}

const settings = deepFreeze({
api: { retry: 3 }
});


И теперь:
settings.api.retry = 10;

console.log(settings.api.retry);
// 3


В обычном режиме присваивание будет молча проигнорировано. В "use strict" — упадёт с TypeError.

Важно: это упрощённая версия deepFreeze. В реальном коде могут всплыть Symbol-свойства, non-enumerable свойства, циклические ссылки и другие детали. Для production-версии обычно используют Reflect.ownKeys() и защиту от циклических ссылок через WeakSet.

Но для понимания главной идеи этого достаточно: Object.freeze() не делает объект глубоко immutable. Он замораживает только первый уровень.

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

📣 JS Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
11👍6🤝5
This media is not supported in your browser
VIEW IN TELEGRAM
👩‍💻 Для удобной работы с .sass-синтаксисом в VS Code!

Sass (.sass only)
добавляет полноценную поддержку indented-синтаксиса Sass: подсветку, автодополнение, навигацию и корректное распознавание .sass-файлов без фигурных скобок и точек с запятой. Помогает комфортно работать со старыми и современными Sass-проектами прямо в редакторе.

📣 JS Ready | #vscode
Please open Telegram to view this post
VIEW IN TELEGRAM
🤝12👍4🔥31
Создаём управляемый Promise без boilerplate!

Раньше, чтобы получить resolve и reject снаружи Promise, приходилось писать так:
let resolve;

const promise = new Promise(res => {
resolve = res;
});


Это работает, но создаёт лишние переменные и выглядит менее аккуратно.

Теперь в JavaScript есть нативный Promise.withResolvers():
const { promise, resolve, reject } =
Promise.withResolvers();


Он сразу возвращает готовый Promise и функции управления им.
resolve('done');
await promise;


Особенно удобно для очередей, WebSocket, Stream API, событийной логики и мостов между callback/event API и async-await.

await в примере работает внутри async-функции или ES-модуля с top-level await. Также проверь поддержку Promise.withResolvers() в своей среде выполнения.

🔥 Promise.withResolvers() убирает boilerplate и делает создание управляемых Promise намного чище и читаемее.

📣 JS Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
11👍6🔥5
🧐 Наткнулся на годную статью на Хабре: «TTF-DOOM: как я запустил 3D-рейкастер внутри TrueType-шрифта»!

В этой статье:
• Показывается, как TrueType hinting VM можно использовать не только для рендеринга шрифтов, но и как полноценную вычислительную среду;
• Разбирается архитектура запуска 3D-рейкастера внутри TTF-шрифта с использованием JavaScript, bytecode и собственного DSL-компилятора;
• Объясняются неожиданные особенности и ограничения TrueType VM.


🔊 Продолжайте читать на Habr!


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

Например, new Date() создаёт объект даты, toISOString() помогает получить дату в UTC-формате, а getTime() — работать с таймстампами и вычислениями.

На картинке — методы и операции для работы с датами, временем, UTC и форматированием.

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

📣 JS Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
🤝12👍65
Как красиво выводить списки без ручных запятых?

Часто нужно показать список технологий, авторов, тегов или участников.

Обычно это начинают собирать вручную:
names.join(', ')


Но в JS есть нативный API — Intl.ListFormat.
newIntl.ListFormat('ru').format(names);


Он сам расставляет запятые, союзы и учитывает правила языка.
newIntl.ListFormat('en').format(names);
// React, Vue, and Svelte


Можно менять тип списка: обычное перечисление, выбор или разделение.
new Intl.ListFormat('ru', {
type: 'disjunction'
}).format(['наличные', 'карта']);
// наличные или карта


🔥 Intl.ListFormat подходит для тегов, участников, категорий, фильтров, хлебных крошек и любых списков в интерфейсе.

📣 JS Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👍5🤝52