В этой статье:
• Показывается, как классическую игру «Змейка» можно полностью переосмыслить, поменяв роли игрока и противников;• Разбирается создание игры на чистом 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
Передавайте AbortSignal через всю цепочку вызовов!
Большинство разработчиков используют
Но намного полезнее сделать
Теперь любая операция выше по стеку может отменить всю цепочку асинхронных вызовов.
Такой подход масштабируется намного лучше, чем создавать новый
🔥
📣 JS Ready | #совет
Большинство разработчиков используют
AbortController только рядом с fetch().const controller = new AbortController();
fetch('/users', {
signal: controller.signal
});
Но намного полезнее сделать
AbortSignal частью API ваших функций.async function loadUser(id, signal) {
const response = await fetch(
`/users/${id}`,
{ signal }
);
return response.json();
}Теперь любая операция выше по стеку может отменить всю цепочку асинхронных вызовов.
const controller = new AbortController();
const user = loadUser(
42,
controller.signal
);
// ...
controller.abort();
Такой подход масштабируется намного лучше, чем создавать новый
AbortController внутри каждой функции. AbortSignal делает API функций композиционным и позволяет отменять сложные операции одной командой.Please open Telegram to view this post
VIEW IN TELEGRAM
❤8👍6🔥4🤝2
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🔥5👍4🤝2
TextEncoder и TextDecoder — работа с байтами и кодировками!
При обычной разработке на JavaScript строки воспринимаются просто как текст. Но когда появляются файлы, сеть, криптография или работа с бинарными API, данных в виде строки уже недостаточно — требуется представление на уровне байтов.
Внутри JavaScript строки используют UTF-16 кодовые единицы, а многие браузерные API работают с бинарными данными (
После вызова
Размер результата зависит от содержимого текста. Символы ASCII занимают один байт, а символы других языков могут занимать несколько байтов. Например:
Обратное преобразование выполняет
По умолчанию используется UTF-8. Если данные приходят из старых систем или файлов с другой кодировкой, можно указать необходимый формат:
Такой вариант часто встречается при работе с устаревшими файлами или внешними системами, которые используют кодировки, отличные от UTF-8.
Один из практических примеров — чтение текстовых файлов через File API:
Метод
В этом примере строка преобразуется в UTF-8 байты, после чего передаётся алгоритму SHA-256 для вычисления хэш-значения.
Отдельно стоит помнить о разнице между длиной строки и размером её бинарного представления:
🔥
📣 JS Ready | #практика
При обычной разработке на JavaScript строки воспринимаются просто как текст. Но когда появляются файлы, сеть, криптография или работа с бинарными API, данных в виде строки уже недостаточно — требуется представление на уровне байтов.
Внутри JavaScript строки используют UTF-16 кодовые единицы, а многие браузерные API работают с бинарными данными (
Uint8Array, ArrayBuffer). Для преобразования текста в байты и обратного восстановления строки используются встроенные TextEncoder и TextDecoder.TextEncoder нужен, когда строку необходимо подготовить для бинарного API. Он кодирует текст в UTF-8 и возвращает объект Uint8Array с последовательностью байтов. Пример:const encoder = new TextEncoder();
const bytes = encoder.encode(
'Hello JavaScript'
);
console.log(bytes);
После вызова
encode() получается массив беззнаковых 8-битных значений. Каждый элемент представляет один байт UTF-8 представления строки.Размер результата зависит от содержимого текста. Символы ASCII занимают один байт, а символы других языков могут занимать несколько байтов. Например:
const encoder = new TextEncoder();
const bytes = encoder.encode(
'Привет'
);
console.log(bytes.length);
bytes.length показывает количество байтов после UTF-8 кодирования. Это значение не равно количеству символов в строке.Обратное преобразование выполняет
TextDecoder:const decoder = new TextDecoder();
const text = decoder.decode(
bytes
);
console.log(text);
decode() принимает бинарные данные (Uint8Array, ArrayBuffer) и преобразует их обратно в обычную JavaScript-строку.По умолчанию используется UTF-8. Если данные приходят из старых систем или файлов с другой кодировкой, можно указать необходимый формат:
const decoder = new TextDecoder(
'windows-1251'
);
const text = decoder.decode(
data
);
console.log(text);
Такой вариант часто встречается при работе с устаревшими файлами или внешними системами, которые используют кодировки, отличные от UTF-8.
Один из практических примеров — чтение текстовых файлов через File API:
const file = input.files[0];
const buffer = await file.arrayBuffer();
const decoder = new TextDecoder();
const text = decoder.decode(
buffer
);
console.log(text);
Метод
arrayBuffer() возвращает содержимое файла в виде бинарного буфера. После этого TextDecoder преобразует полученные байты обратно в текст.TextEncoder также часто используется вместе с Web Crypto API. Криптографические методы работают не со строками, а с бинарными данными, поэтому перед вычислением хэша текст необходимо сначала закодировать:const encoder = new TextEncoder();
const data = encoder.encode(
'password'
);
const hash = await crypto.subtle.digest(
'SHA-256',
data
);
console.log(
new Uint8Array(hash)
);
В этом примере строка преобразуется в UTF-8 байты, после чего передаётся алгоритму SHA-256 для вычисления хэш-значения.
Отдельно стоит помнить о разнице между длиной строки и размером её бинарного представления:
const text = 'Привет';
console.log(text.length);
const bytes = new TextEncoder()
.encode(text);
console.log(bytes.length);
text.length показывает количество UTF-16 кодовых единиц, а bytes.length — количество байтов в UTF-8 представлении. Эти значения могут отличаться.TextEncoder и TextDecoder используются во многих Web API: при работе с файлами, потоками данных, сетевыми протоколами и криптографическими операциями. Они позволяют напрямую преобразовывать текстовое представление в бинарное и обратно без сторонних библиотек.Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍6🔥4🤝1
Крутая статья лежит на Хабре: «Пишем Pac-Man на чистом JavaScript: ностальгия, “Пиксели” и туман войны»!
В этой статье:
🔊 Продолжайте читать на Habr!
📣 JS Ready | #статья
В этой статье:
• Разбирается создание собственной версии культовой игры Pac-Man с нуля без игровых движков и сторонних библиотек;• Показывается реализация игровой логики, движения персонажа, поведения призраков и системы столкновений на чистом JavaScript;• Подробно описывается добавление необычной механики «тумана войны», адаптация управления под ПК и мобильные устройства, а также архитектура проекта.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍8❤4
Например,
fetch() используется для современных HTTP-запросов через Promise, Axios упрощает работу с API в браузере и Node.js, а XMLHttpRequest и jQuery AJAX чаще встречаются в старых проектах.На картинке — основные способы отправки HTTP-запросов в JavaScript: XMLHttpRequest, Fetch API, Axios и jQuery AJAX, а также примеры получения данных с сервера через REST API.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤7🔥5