
Современный JavaScript давно перестал быть языком, который используется только для простых эффектов на странице. Сегодня браузер предоставляет разработчику мощный набор встроенных возможностей, позволяющий создавать интерактивные интерфейсы, работать с API, DOM, событиями, асинхронными операциями, файлами и данными — зачастую без единой сторонней библиотеки.
Когда-то разработка интерфейса практически автоматически означала подключение jQuery или другой библиотеки. Сегодня ситуация изменилась.Современный браузер уже содержит большое количество API, которые раньше приходилось получать из сторонних решений.
DOM, Fetch API, Promise, WebSocket, Web Storage, ES-модули, события, классы, async/await, современные методы массивов и строк — всё это доступно непосредственно в JavaScript.
Поэтому подход JavaScript без библиотек, который часто называют vanilla JavaScript, снова становится особенно интересным. Это не означает отказ от библиотек вообще. Речь идёт о понимании того, что значительную часть задач можно решить средствами самого языка и браузера.
ECMAScript развивается ежегодно. Последние версии JavaScript получили множество возможностей, которые ещё несколько лет назад потребовали бы дополнительных функций или собственных реализаций.
В ECMAScript 2026 появились, среди прочего,Math.sumPrecise(), Iterator.concat(), Array.fromAsync(), Error.isError(), новые методы Map и WeakMap, а также новые возможности работы с JSON и бинарными данными.
Это хорошо показывает направление развития языка: JavaScript получает всё больше встроенных инструментов, а разработчику всё реже приходится писать собственные вспомогательные функции.
Одной из интересных возможностей современного JavaScript является примитивный тип Symbol.
Symbol предназначен прежде всего для создания уникальных идентификаторов. Каждый новый вызов Symbol() создаёт уникальное значение.
const first = Symbol();
const second = Symbol();
console.log(first === second);
// false
Даже если передать одинаковое описание, символы всё равно будут разными:
const a = Symbol("id");
const b = Symbol("id");
console.log(a === b);
// falseСтрока "id" в данном случае является только описанием символа и не превращает его в обычную строку.
Главное практическое применение Symbol — создание уникальных ключейсвойств объектов.
const id = Symbol("id");
const user = {
name: "Иван",
[id]: 12345
};
console.log(user[id]);
// 12345Это позволяет создавать свойства, имена которых не конфликтуютс обычными строковыми ключами.
Например, сторонний код может добавить объекту свойство id, но уникальный Symbol останется отдельным ключом:
const privateId = Symbol("id");
const user = {
id: 10,
name: "Иван",
[privateId]: 500
};
console.log(user.id);
// 10
console.log(user[privateId]);
// 500Symbol не является полноценным механизмом приватности, но он позволяет создавать свойства, которые не участвуют в обычном перечислении объекта.
Интересная особенность символов заключается в том, что они не попадают в обычный список ключей объекта.
const secret = Symbol("secret");
const user = {
name: "Иван",
[secret]: 123
};
console.log(Object.keys(user));
// ["name"]Однако получить символьные ключи можно отдельно:
console.log(Object.getOwnPropertySymbols(user));
// [Symbol(secret)]
А если необходимо получить одновременно строковые и символьные ключи, можно использовать:
console.log(Reflect.ownKeys(user));
Это важный момент для разработчиков библиотек и CMS. Если код использует только Object.keys(), символьные свойства объекта он не увидит.
Обычный Symbol() всегда создаёт новый символ. Но иногда необходимо получить один и тот же символ по определённому ключу.
Для этого используется Symbol.for().
const first = Symbol.for("user.id");
const second = Symbol.for("user.id");
console.log(first === second);
// trueВ отличие от обычного Symbol(), одинаковый ключ в глобальном реестре возвращает тот же самый Symbol.
const key = Symbol.for("ngcms.plugin");
console.log(Symbol.keyFor(key));
// ngcms.pluginТакой механизм может быть полезен для взаимодействия разных частей приложения, которым необходимо договориться об одном уникальном ключе.
JavaScript содержит специальные встроенные символы, которые называются well-known Symbols.
Например:
Они позволяют изменять стандартное поведение объектов и взаимодействоватьс механизмами самого языка.
Один из самых интересных примеров — Symbol.iterator. Именно он позволяет объекту работать с конструкцией for...of.
const collection = {
values: [10, 20, 30],
*[Symbol.iterator]() {
yield* this.values;
}
};
for (const value of collection) {
console.log(value);
}Таким образом, разработчик может сделать собственный объект и определить, каким образом его содержимое будет перебираться.
Это особенно интересно при создании собственных коллекций, итераторов и API без использования сторонних библиотек.
Современный JavaScript всё больше внимания уделяет итераторам. В ECMAScript 2025 появился глобальный объект Iterator, а ECMAScript 2026 продолжает это направление.
Одной из новых возможностей стал Iterator.concat(), позволяющий объединять несколько итераторов в последовательность.
const first = [1, 2];
const second = [3, 4];
const result = Iterator.concat(first, second);
console.log([...result]);
// [1, 2, 3, 4]
Итераторы особенно полезны при обработке больших объёмов данных, поскольку позволяют работать с последовательностью значений без необходимости создавать огромный промежуточный массив.
В ECMAScript 2026 появился Array.fromAsync().Он позволяет создавать массив из асинхронного источника данных.
async function load() {
const values = await Array.fromAsync(
getAsyncValues()
);
console.log(values);
}Это особенно удобно при работе с асинхронными итераторами, потоками данных и современными API.
JavaScript традиционно использует числа с плавающей точкой, поэтому некоторые арифметические операции могут давать неожиданные результаты.
console.log(0.1 + 0.2);
// 0.30000000000000004
ECMAScript 2026 добавляет Math.sumPrecise(),предназначенный для суммирования набора чисел с уменьшением потери точности.
const values = [
0.1,
0.2,
0.3
];
const total = Math.sumPrecise(values);
console.log(total);
Такая возможность может быть полезна при обработке финансовых, статистических и других числовых данных, где накопление ошибки при суммировании имеет значение.
В современном JavaScript ошибки могут быть представлены разными объектами. ECMAScript 2026 добавляет Error.isError(), предназначенный для проверки, является ли значение объектом ошибки.
try {
throw new Error("Ошибка");
} catch (error) {
if (Error.isError(error)) {
console.log(error.message);
}
}Это удобно при разработке универсального кода обработки исключений, особенно если данные могут приходить из разных источников.
JSON используется практически в каждом современном веб-приложении. Поэтому изменения в API JSON важны для JavaScript-разработчиков.
ECMAScript 2026 расширяет возможности JSON.parse() и добавляет JSON.rawJSON().
Это позволяет разработчику получать больше контроля над преобразованием JSON и формированием результата через JSON.stringify().
const data = JSON.parse(
'{"name":"PHP","version":8.5}'
);
console.log(data.name);
// PHP
Для разработчиков CMS это особенно интересно, поскольку JSON является основным форматом обмена данными между браузером, сервером и API.
Для большинства небольших интерфейсных задач библиотека вообще не обязательна.
const button = document.querySelector("#load");
button.addEventListener("click", async () => {
const response = await fetch("/api/news");
const data = await response.json();
console.log(data);
});Здесь нет jQuery, Axios или другой библиотеки. Используются стандартные возможности браузера: querySelector(), события, fetch(), Promise и async/await.
JavaScript без библиотек не означает, что библиотеки стали бесполезными. Большие проекты могут значительно выиграть от готовой архитектуры, компонентов, экосистемы и инструментов конкретного фреймворка.
Но для небольшого сайта подключение огромной библиотеки ради одной кнопки или AJAX-запроса может быть неоправданным.
Хороший разработчик должен уметь работать и с библиотеками, и с чистым JavaScript, выбирая подходящий инструмент для конкретной задачи.
Изучение vanilla JavaScript позволяет понять фундаментальные механизмы, на которых затем работают библиотеки и фреймворки.
В первую очередь стоит хорошо знать:
После этого переход к React, Vue, Svelte или другому инструменту становится значительно понятнее.
Современный JavaScript уже давно не ограничивается несколькими функциями для изменения HTML-страницы. Сам язык и браузерная платформа предоставляют разработчику огромный набор возможностей.
Особенно интересен тип Symbol, который позволяет создавать уникальные ключи объектов и участвовать во внутренних механизмах JavaScript, например через Symbol.iterator.
Одновременно развивается и сам ECMAScript. Новые возможности 2026 года, такие как Iterator.concat(), Array.fromAsync(), Math.sumPrecise(), Error.isError(), улучшения JSON и работа с бинарными данными, показывают, что язык продолжает получать всё более специализированные встроенные инструменты.
Поэтому современный подход выглядит достаточно просто: сначала знать возможности самого JavaScript, а уже потом решать, нужна ли для конкретной задачи библиотека.
Для небольших сайтов, CMS, административных панелей и отдельных интерактивных элементов чистого JavaScript часто вполне достаточно. А главное — такой код легче понять, отладить и не всегда требуется загружать на страницу дополнительную зависимость.