Например, после ввода URL браузер выполняет цепочку операций: разрешение DNS, установка HTTPS-соединения, отправка HTTP-запроса, получение ресурсов и запуск механизма рендеринга.
На картинке — полный жизненный цикл обработки страницы: от сетевого взаимодействия до построения DOM/CSSOM, выполнения JavaScript Engine и формирования итогового интерфейса.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🤝5🔥4
Temporal API — замена Date в JavaScript!
Создадим объект календарной даты без привязки к времени:
Работа с датами становится более очевидной:
В отличие от
Для точного момента времени используется другой тип:
Часовые пояса теперь являются отдельной частью модели:
Вместо ручных вычислений смещений
Можно безопасно получать локальные компоненты даты:
Это устраняет большое количество ошибок, которые возникают при использовании
Ещё один практический сценарий — сравнение дат:
Вместо сложных преобразований в миллисекунды используется понятное сравнение:
🔥
📣 JS Ready | #практика
Date существует в JavaScript с первых версий языка и до сих пор используется повсеместно, но у него есть несколько архитектурных проблем: изменяемость объектов, сложная работа с часовыми поясами и неоднозначное поведение при преобразовании дат.Temporal — это новый API, который предлагает более предсказуемую модель работы с датами и временем: отдельные типы для даты, времени, момента во времени и часовых поясов.Создадим объект календарной даты без привязки к времени:
const birthday = Temporal.PlainDate.from(
"1995-08-15"
);
console.log(birthday);
// 1995-08-15
PlainDate хранит только дату: год, месяц и день. Он не зависит от часового пояса и подходит для дней рождения, сроков действия, календарных событий.Работа с датами становится более очевидной:
const nextWeek = birthday.add({
days: 7
});
console.log(nextWeek);
// 1995-08-22
В отличие от
Date, объекты Temporal являются иммутабельными: методы не изменяют исходное значение, а возвращают новый объект.Для точного момента времени используется другой тип:
const now = Temporal.Now.instant();
console.log(now);
// 2026-07-15T12:30:45.123Z
Instant представляет конкретную точку на временной шкале и всегда хранится в UTC. Это удобно для логов, событий, транзакций и любых данных, где важна абсолютная точность.Часовые пояса теперь являются отдельной частью модели:
const zoned = now.toZonedDateTimeISO(
"Europe/Warsaw"
);
console.log(zoned);
Вместо ручных вычислений смещений
Temporal явно связывает момент времени с конкретной временной зоной.Можно безопасно получать локальные компоненты даты:
console.log(zoned.hour);
console.log(zoned.day);
console.log(zoned.month);
Это устраняет большое количество ошибок, которые возникают при использовании
getHours(), getDate() и ручной работе с UTC.Ещё один практический сценарий — сравнение дат:
const start = Temporal.PlainDate.from(
"2026-01-01"
);
const end = Temporal.PlainDate.from(
"2026-12-31"
);
Вместо сложных преобразований в миллисекунды используется понятное сравнение:
console.log(
Temporal.PlainDate.compare(start, end)
);
// -1
Temporal разделяет разные сущности времени, поэтому код становится понятнее: дата, время, момент и часовой пояс больше не смешиваются в одном объекте.Temporal — это переработанная модель работы со временем, которая решает основные проблемы старого Date: мутабельность, часовые пояса и сложные преобразования. Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤6🔥4
Получаем размер данных в байтах без ручных подсчётов!
Когда нужно узнать размер строки или подготовленных данных, многие используют:
Но
В JavaScript есть нативный способ —
Он показывает размер содержимого
Например:
Emoji занимает 2 UTF-16 code units, но в
Полезно перед загрузкой файлов, отправкой данных через API, проверкой лимитов и работой с бинарными данными.
Для файлов ещё проще:
🔥
📣 JS Ready | #совет
Когда нужно узнать размер строки или подготовленных данных, многие используют:
str.length
Но
length считает количество UTF-16 кодовых единиц, а не размер данных в байтах.В JavaScript есть нативный способ —
Blob.const size = new Blob([data]).size;
Он показывает размер содержимого
Blob в байтах.Например:
new Blob(['😀']).size;
// 4
'😀'.length;
// 2
Emoji занимает 2 UTF-16 code units, но в
Blob превращается в 4 байта UTF-8.Полезно перед загрузкой файлов, отправкой данных через API, проверкой лимитов и работой с бинарными данными.
Для файлов ещё проще:
file.size;
Blob.size — простой нативный способ узнать размер данных в байтах без сторонних библиотек.Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤6🔥6
Например, cookies позволяют браузеру хранить небольшие данные на стороне клиента, а sessions переносят хранение пользовательского состояния на сервер, оставляя у клиента только идентификатор сессии.
На картинке — основное отличие между Cookies и Sessions, которое помогает понять, где хранить данные пользователя при разработке систем аутентификации.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤5🔥4
Например, TLS-сертификат подтверждает подлинность сервера, а обмен ключами позволяет безопасно создать сессионный ключ для дальнейшего шифрования данных.
На картинке — основные этапы работы HTTPS: TCP handshake, проверка сертификата через Certificate Authority, обмен ключами, создание защищённой сессии, симметричное шифрование и безопасная передача данных между клиентом и сервером.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍6🔥6
Цифровая подпись данных через Web Crypto API!
Цифровая подпись позволяет проверить не только целостность данных, но и подтвердить, что они были созданы владельцем определённого ключа. В браузере для этого можно использовать встроенный Web Crypto API через
Создадим пару RSA-ключей с алгоритмом RSA-PSS и SHA-256. Приватный ключ будет использоваться для создания подписи, а публичный — для проверки её корректности.
После генерации мы получаем два ключа. Приватный ключ должен оставаться защищённым, потому что его утечка позволит создавать подписи от имени владельца. Публичный ключ можно передавать другим участникам для проверки подписей.
Перед созданием подписи данные необходимо преобразовать в бинарный формат, так как криптографические операции работают с байтами, а не со строками.
Теперь создадим цифровую подпись для подготовленных данных с использованием приватного ключа. Результат можно сохранить вместе с данными и использовать позже для проверки подлинности.
Цифровая подпись не скрывает содержимое сообщения и не заменяет шифрование. Она подтверждает, что данные были подписаны соответствующим приватным ключом и не были изменены после создания подписи.
Для проверки используется публичный ключ, исходные данные и полученная подпись. Метод
Если изменить данные после создания подписи, проверка завершится неудачно, так как подпись была создана для другого содержимого.
Важно понимать разницу между цифровой подписью и шифрованием. Шифрование защищает конфиденциальность данных, а подпись подтверждает их происхождение и целостность. Такие механизмы используются при проверке обновлений программного обеспечения, обмене данными между сервисами, защите конфигураций, API-аутентификации и электронном документообороте.
🔥
📣 JS Ready | #практика
Цифровая подпись позволяет проверить не только целостность данных, но и подтвердить, что они были созданы владельцем определённого ключа. В браузере для этого можно использовать встроенный Web Crypto API через
crypto.subtle, который поддерживает генерацию ключей, создание подписей и их проверку.Создадим пару RSA-ключей с алгоритмом RSA-PSS и SHA-256. Приватный ключ будет использоваться для создания подписи, а публичный — для проверки её корректности.
const keys = await crypto.subtle.generateKey(
{
name: "RSA-PSS",
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256"
},
true,
["sign", "verify"]
);
После генерации мы получаем два ключа. Приватный ключ должен оставаться защищённым, потому что его утечка позволит создавать подписи от имени владельца. Публичный ключ можно передавать другим участникам для проверки подписей.
Перед созданием подписи данные необходимо преобразовать в бинарный формат, так как криптографические операции работают с байтами, а не со строками.
const data = new TextEncoder()
.encode("order=123");
Теперь создадим цифровую подпись для подготовленных данных с использованием приватного ключа. Результат можно сохранить вместе с данными и использовать позже для проверки подлинности.
const signature = await crypto.subtle.sign(
{
name: "RSA-PSS",
saltLength: 32
},
keys.privateKey,
data
);
Цифровая подпись не скрывает содержимое сообщения и не заменяет шифрование. Она подтверждает, что данные были подписаны соответствующим приватным ключом и не были изменены после создания подписи.
Для проверки используется публичный ключ, исходные данные и полученная подпись. Метод
verify() возвращает true, если подпись соответствует переданному содержимому.const valid = await crypto.subtle.verify(
{
name: "RSA-PSS",
saltLength: 32
},
keys.publicKey,
signature,
data
);
console.log(valid);
// true
Если изменить данные после создания подписи, проверка завершится неудачно, так как подпись была создана для другого содержимого.
const changedData = new TextEncoder()
.encode("order=999");
const changed = await crypto.subtle.verify(
{
name: "RSA-PSS",
saltLength: 32
},
keys.publicKey,
signature,
changedData
);
console.log(changed);
// false
Важно понимать разницу между цифровой подписью и шифрованием. Шифрование защищает конфиденциальность данных, а подпись подтверждает их происхождение и целостность. Такие механизмы используются при проверке обновлений программного обеспечения, обмене данными между сервисами, защите конфигураций, API-аутентификации и электронном документообороте.
crypto.subtle показывает, что Web Crypto API — это полноценный криптографический инструмент в браузере, который позволяет работать не только с хэшированием, но и с ключами, цифровыми подписями и проверкой подлинности данных.Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤5🔥3🤝1
This media is not supported in your browser
VIEW IN TELEGRAM
Например, Imperative Programming позволяет описывать код пошагово через команды и изменение состояния, Functional Programming строит логику через функции и работу с данными, а OOP организует код вокруг объектов, классов и их взаимодействия.
На картинке — основное отличие между тремя подходами к программированию, которые используются в JavaScript и помогают выбирать правильный стиль при разработке приложений.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍5🔥4
Копируем объект вместе с его логикой, а не только значениями!
Многие используют
Но такой способ переносит только значения свойств. Если у объекта есть
Для полного копирования структуры объекта есть
Он возвращает описание каждого свойства:
Теперь можно создать копию, сохранив оригинальное поведение:
Например,
После копирования:
а не просто сохранённое значение.
🔥
📣 JS Ready | #совет
Многие используют
spread или Object.assign() для копирования объектов:const copy = { ...user };Но такой способ переносит только значения свойств. Если у объекта есть
getter, setter или специальные настройки свойства — они будут потеряны.Для полного копирования структуры объекта есть
Object.getOwnPropertyDescriptors().const descriptors = Object.getOwnPropertyDescriptors(obj);
Он возвращает описание каждого свойства:
{
value: 'Alex',
writable: true,
enumerable: true,
configurable: true
}Теперь можно создать копию, сохранив оригинальное поведение:
const clone = Object.defineProperties(
{},
Object.getOwnPropertyDescriptors(obj)
);
Например,
getter останется getter-ом:const user = {
first: 'Alex',
get name() {
return this.first;
}
};После копирования:
clone.name;
// Alex
а не просто сохранённое значение.
Object.getOwnPropertyDescriptors() полезен при создании библиотек, расширении объектов, работе с классами и когда важно сохранить не только данные, но и поведение объекта.Please open Telegram to view this post
VIEW IN TELEGRAM
❤11👍7🔥5
В этой статье:
• Показывается, как классическую игру «Змейка» можно полностью переосмыслить, поменяв роли игрока и противников;• Разбирается создание игры на чистом JavaScript и Canvas без фреймворков, сборщиков и готовых игровых движков;• Подробно описывается разработка игровой логики, ИИ змей, адаптация под мобильные устройства и балансировка сложности.Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥8❤6
Разбираем RegExp.escape() — стандартный способ экранирования динамических шаблонов!
При построении регулярных выражений из динамических данных долгое время приходилось писать собственные функции экранирования или использовать сторонние утилиты. Такие реализации редко учитывали все особенности синтаксиса регулярных выражений и часто отличались друг от друга.
Создадим регулярное выражение из динамического значения:
В этом примере экранируется только динамическая часть шаблона. Остальная логика (
Такой подход особенно полезен, когда шаблон состоит из статической и динамической частей:
Без экранирования точка внутри строки интерпретировалась бы как метасимвол регулярного выражения, а не как обычный символ.
Ещё один распространённый сценарий — поиск по произвольному пользовательскому запросу:
В этом случае строка всегда интерпретируется буквально, независимо от специальных символов.
Важно понимать:
🔥
📣 JS Ready | #практика
При построении регулярных выражений из динамических данных долгое время приходилось писать собственные функции экранирования или использовать сторонние утилиты. Такие реализации редко учитывали все особенности синтаксиса регулярных выражений и часто отличались друг от друга.
RegExp.escape() стандартизирует эту задачу. Метод принимает строку и возвращает строку, которую можно безопасно использовать как буквальный фрагмент шаблона регулярного выражения.Создадим регулярное выражение из динамического значения:
const filename = "app.config.js";
const regex = new RegExp(
`^${RegExp.escape(filename)}$`
);
console.log(
regex.test("app.config.js")
);
// true
В этом примере экранируется только динамическая часть шаблона. Остальная логика (
^ и $) остаётся полноценным регулярным выражением.Такой подход особенно полезен, когда шаблон состоит из статической и динамической частей:
const extension = "tar.gz";
const regex = new RegExp(
`\\.${RegExp.escape(extension)}$`
);
console.log(
regex.test("archive.tar.gz")
);
// true
Без экранирования точка внутри строки интерпретировалась бы как метасимвол регулярного выражения, а не как обычный символ.
Ещё один распространённый сценарий — поиск по произвольному пользовательскому запросу:
const query = "[admin]";
const text = "Users: [admin], [guest]";
const regex = new RegExp(
RegExp.escape(query),
"gi"
);
const matches = text.match(regex);
console.log(matches);
// ["[admin]"]
В этом случае строка всегда интерпретируется буквально, независимо от специальных символов.
Важно понимать:
RegExp.escape() предназначен для экранирования обычного текста. Метод принимает только строки — если передать объект RegExp, будет выброшен TypeError. Также не стоит применять его к фрагментам, которые должны остаться частью регулярного выражения.RegExp.escape() предоставляет стандартный и корректный способ экранирования динамических фрагментов регулярных выражений. В современных JavaScript-окружениях собственные утилиты для этой задачи обычно больше не нужны. Если же требуется поддержка старых браузеров или версий Node.js, стоит использовать полифил.Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤5🔥5
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11👍7🔥5
This media is not supported in your browser
VIEW IN TELEGRAM
LearnJS — русскоязычный учебник, от базовых понятий до продвинутых тем чтобы освоить JS!
Удобные объяснения, примеры кода, интерактивные задания помогут прокачать навыки как новичкам, так и опытным разработчикам.
📌 Оставляю ссылочку: learnjs.ru
📣 JS Ready | #сайт
Удобные объяснения, примеры кода, интерактивные задания помогут прокачать навыки как новичкам, так и опытным разработчикам.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥7❤3
This media is not supported in your browser
VIEW IN TELEGRAM
Regulex — это онлайн-инструмент для визуализации регулярных выражений в JavaScript, который преобразует их в диаграммы, помогая легче понять сложные паттерны.
📌 Ссылочка: jex.im/regulex
📣 JS Ready | #сайт
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍4🔥4
Nullish coalescing (??) — отличие от логического OR (||)!
В JavaScript операторы
Оператор
В результате будет возвращено 100, хотя переменная содержит определённое значение. Для числовых параметров, счётчиков и флагов такое поведение часто является нежелательным.
Оператор
В этом случае результатом будет 0, потому что значение существует и не является null или undefined.
Разница особенно заметна при обработке объектов настроек. Частая ошибка — использовать
После выполнения переменная получит true, хотя исходное значение явно отключало параметр.
При использовании
Теперь значение false не будет заменено значением по умолчанию.
Оператор
Если объект config, поле api или свойство timeout отсутствуют, будет использовано значение 5000. При этом существующее значение 0 останется без изменений.
Есть важный синтаксический момент: JavaScript запрещает смешивать
Разработчик должен явно определить порядок вычисления, чтобы избежать неоднозначности.
или таким образом:
Такой синтаксический запрет сделан намеренно: выражения с несколькими операторами разных типов становятся сложными для анализа даже при небольшом изменении логики.
При работе с API, формами и пользовательским вводом
В данном случае сохраняется пустая строка, потому что она является переданным значением, а не отсутствием данных.
🔥
📣 JS Ready | #практика
В JavaScript операторы
|| и ?? решают похожую задачу — выбор значения по умолчанию, но работают с разной моделью проверки. Это особенно важно при обработке конфигураций, параметров функций и данных из внешних источников, где 0, false и пустая строка могут быть корректными значениями.Оператор
|| использует проверку на truthy/falsy, поэтому заменяет любое значение, которое JavaScript считает ложным.const limit = 0;
console.log(
limit || 100
);
В результате будет возвращено 100, хотя переменная содержит определённое значение. Для числовых параметров, счётчиков и флагов такое поведение часто является нежелательным.
Оператор
?? использует другую проверку: запасное значение применяется только при null или undefined.const limit = 0;
console.log(
limit ?? 100
);
В этом случае результатом будет 0, потому что значение существует и не является null или undefined.
Разница особенно заметна при обработке объектов настроек. Частая ошибка — использовать
|| там, где поле может содержать валидное falsy-значение.const options = {
enabled: false
};
const enabled =
options.enabled || true;
После выполнения переменная получит true, хотя исходное значение явно отключало параметр.
При использовании
?? сохраняется исходная логика:const enabled =
options.enabled ?? true;
Теперь значение false не будет заменено значением по умолчанию.
Оператор
?? часто используется вместе с optional chaining, когда структура объекта заранее неизвестна. Такой вариант позволяет безопасно получать вложенные значения без дополнительных проверок на каждом уровне.const timeout =
config?.api?.timeout ?? 5000;
Если объект config, поле api или свойство timeout отсутствуют, будет использовано значение 5000. При этом существующее значение 0 останется без изменений.
Есть важный синтаксический момент: JavaScript запрещает смешивать
?? с логическими операторами || и && без явных скобок. Следующее выражение приведёт к ошибке парсинга:a ?? b || c;
Разработчик должен явно определить порядок вычисления, чтобы избежать неоднозначности.
(a ?? b) || c;
или таким образом:
a ?? (b || c);
Такой синтаксический запрет сделан намеренно: выражения с несколькими операторами разных типов становятся сложными для анализа даже при небольшом изменении логики.
При работе с API, формами и пользовательским вводом
?? позволяет отделить отсутствие значения от значения, которое просто является falsy. Например, пустая строка может быть частью бизнес-логики и не должна автоматически заменяться.const title = "";
const result =
title ?? "Untitled";
В данном случае сохраняется пустая строка, потому что она является переданным значением, а не отсутствием данных.
?? стоит использовать там, где требуется различать null/undefined и остальные значения. В отличие от ||, он не изменяет корректные falsy-данные и делает логику работы со значениями по умолчанию более точной.Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤8🔥6
Например, в глобальной области
this зависит от окружения выполнения, в методе объекта — ссылается на сам объект, а в обычной функции его значение определяется способом вызова.На картинке — все основные случаи работы
this: глобальный контекст, методы объектов, обычные функции, стрелочные функции, обработчики событий, а также управление контекстом через call(), apply() и bind().Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤6🤝3🔥1
Intl.DurationFormat позволяет красиво выводить интервалы времени без ручной сборки строк: годы, месяцы, дни, часы, минуты и секунды автоматически форматируются с учетом языка и правил локализации.На картинке — основные варианты использования
Intl.DurationFormat, разные стили отображения (long, short, narrow, digital) и примеры форматирования длительности для разных локалей.Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍7🔥7