Введение

Язык программирования высокого уровня

использование JavaScript в Википедии

JavaScript ('/dʒ//ɑː//v//ə//s//k//r//ɪ//p//t/'), часто сокращаемый как JS, — это язык программирования и одна из основных технологий Веба, наряду с HTML и CSS. 99% веб-сайтов используют JavaScript на стороне клиента для обеспечения поведения веб-страниц. Веб-браузеры имеют выделенный JavaScript-движок, который выполняет клиентский код. Эти движки также используются в некоторых серверах и в различных приложениях. Наиболее популярной средой выполнения для использования вне браузера является Node.js. JavaScript — это язык программирования высокого уровня, часто компилируемый в режиме реального времени, соответствующий стандарту ECMAScript. Он имеет динамическую типизацию, объектно-ориентированное программирование на основе прототипов и функции первого класса. Это мультипарадигменный язык, поддерживающий стили программирования, основанные на событиях, функциональное и императивное программирование. Он предоставляет интерфейсы прикладного программирования (API) для работы с текстом, датами, регулярными выражениями, стандартными структурами данных и объектной моделью документа (DOM). Стандарт ECMAScript не включает в себя какие-либо средства ввода/вывода (I/O), такие как сетевые возможности, хранилище или графические функции. На практике веб-браузер или другая среда выполнения предоставляет JavaScript API для ввода/вывода. Хотя Java и JavaScript похожи по названию, синтаксису и соответствующим стандартным библиотекам, это два разных языка, сильно отличающихся по своей архитектуре.

Создание в Netscape

Первый популярный веб-браузер с графическим пользовательским интерфейсом, Mosaic, был выпущен в 1993 году. Доступный для людей без специальных технических знаний, он сыграл заметную роль в быстром росте ранней Всемирной паутины. Ведущие разработчики Mosaic затем основали корпорацию Netscape, которая выпустила более отполированный браузер Netscape Navigator в 1994 году. Он быстро стал самым используемым. В эти формирующиеся годы развития Сети веб-страницы могли быть только статичными, лишенными возможности динамического поведения после загрузки страницы в браузере. В развивающейся среде веб-разработки возникло стремление устранить это ограничение, поэтому в 1995 году Netscape решила добавить язык программирования в Navigator. Для этого были предприняты два подхода: сотрудничество с Sun Microsystems для внедрения языка Java и найм Брендана Айха для внедрения языка Scheme. Целью был "язык для широких масс", и руководство Netscape вскоре решило, что наилучшим вариантом будет, если Айх разработает новый язык с синтаксисом, похожим на Java, и менее похожим на Scheme или другие существующие скриптовые языки. Выбор названия JavaScript вызвал замешательство, создавая впечатление о прямой связи с Java. В то время бум доткомов только начинался, и Java был популярным новым языком, поэтому Айх рассматривал название JavaScript как маркетинговый ход Netscape.

Принятие Microsoft

Microsoft представила Internet Explorer в 1995 году, что привело к войне браузеров с Netscape. В области JavaScript Microsoft разработала собственный интерпретатор под названием JScript. Microsoft впервые выпустила JScript в 1996 году, одновременно с начальной поддержкой CSS и расширениями для HTML. Каждая из этих реализаций значительно отличалась от аналогов в Netscape Navigator. Эти различия затрудняли разработчикам обеспечение корректной работы их веб-сайтов в обоих браузерах, что привело к широкому распространению логотипов "лучше всего просматривается в Netscape" и "лучше всего просматривается в Internet Explorer" на протяжении нескольких лет.

Появление JScript

Брендан Эйх позже вспоминал об этом периоде так: "Это по-прежнему язык второго плана. Его считают медленным или надоедливым. Люди использовали всплывающие окна или те самые бегущие строки в старой строке состояния внизу старого браузера". В итоге JScript стал фактическим стандартом для клиентского скриптинга в интернете. Microsoft изначально принимала участие в процессе стандартизации и внедрила некоторые предложения в свой язык JScript, но со временем перестала сотрудничать в рамках ECMA. В результате разработка ECMAScript 4 была приостановлена.

Рост и стандартизация

В период доминирования Internet Explorer в начале 2000-х годов разработка клиентского скриптинга находилась в застое. Это начало меняться в 2004 году, когда преемник Netscape, Mozilla, выпустила браузер Firefox. Firefox был хорошо принят многими и завоевал значительную долю рынка у Internet Explorer. В 2005 году Mozilla присоединилась к ECMA International, и началась работа над стандартом ECMAScript for XML (E4X). Это привело к совместной работе Mozilla с Macromedia (позже приобретенной Adobe Systems), которые внедряли E4X в свой язык ActionScript 3, основанный на черновике ECMAScript 4. Целью стало стандартизировать ActionScript 3 как новый ECMAScript 4. Для этого Adobe Systems выпустила реализацию Tamarin как проект с открытым исходным кодом. Однако Tamarin и ActionScript 3 слишком отличались от устоявшегося клиентского скриптинга, и без сотрудничества Microsoft ECMAScript 4 так и не был завершен. Тем временем важные разработки происходили в независимых сообществах с открытым исходным кодом. В 2005 году Джесси Джеймс Гарретт опубликовал аналитическую статью, в которой ввел термин Ajax и описал набор технологий, основой которых был JavaScript, для создания веб-приложений, позволяющих загружать данные в фоновом режиме без перезагрузки всей страницы. Это положило начало периоду возрождения JavaScript, возглавляемому библиотеками с открытым исходным кодом и сообществами вокруг них. Было создано множество новых библиотек, включая jQuery, Prototype, Dojo Toolkit и MooTools. В 2008 году Google представила браузер Chrome с движком V8 JavaScript, который превосходил конкурентов по скорости. Ключевым нововведением была JIT-компиляция (компиляция в реальном времени), поэтому другим производителям браузеров пришлось модернизировать свои движки для поддержки JIT. В июле 2008 года все эти различные стороны собрались на конференции в Осло. Это привело к соглашению в начале 2009 года объединить все соответствующие работы и продвигать язык вперед. Результатом стал стандарт ECMAScript 5, выпущенный в декабре 2009 года.

Достижение зрелости

Амбициозная работа над языком продолжалась несколько лет и завершилась публикацией ECMAScript 6 в 2015 году, формализовав обширный набор дополнений и улучшений. Создание Node.js Райаном Далем в 2009 году привело к значительному увеличению использования JavaScript вне веб-браузеров. Node.js объединяет движок V8, цикл обработки событий и API ввода-вывода, предоставляя тем самым автономную среду выполнения JavaScript. К 2018 году Node.js использовался миллионами разработчиков, а npm содержал наибольшее количество модулей среди всех менеджеров пакетов в мире. В настоящее время проект спецификации ECMAScript поддерживается в открытом доступе на GitHub, а потенциальные изменения в языке проходят тщательную проверку через всесторонний процесс подачи предложений. Теперь разработчики отслеживают статус новых функций по отдельности, а не ориентируются на номера версий. Торговая марка была первоначально зарегистрирована за Sun Microsystems 6 мая 1997 года и перешла к Oracle после приобретения Sun в 2009 году.

Использование веб-сайта на стороне клиента

JavaScript является доминирующим языком клиентской стороны для веб-разработки, и 99% всех веб-сайтов используют его для этих целей. jQuery – наиболее часто используемый. Однако термин "Vanilla JS" возник для обозначения веб-сайтов, которые вообще не используют библиотеки или фреймворки, а полагаются исключительно на стандартную функциональность JavaScript.

Другие виды использования

Использование JavaScript расширилось за пределы его изначального применения в веб-браузерах. JavaScript-движки теперь встроены в различные другие программные системы, как для серверной части веб-сайтов, так и для приложений, не связанных с браузерами. Первые попытки популяризации JavaScript на стороне сервера были предприняты с помощью Netscape Enterprise Server и Microsoft Internet Information Services, однако они занимали небольшие ниши. Electron, Cordova, React Native и другие прикладные фреймворки использовались для создания множества приложений, поведение которых реализовано на JavaScript. К другим приложениям, не связанным с браузерами, относятся поддержка скриптов PDF-документов в Adobe Acrobat и расширения GNOME Shell, написанные на JavaScript. В последнее время JavaScript начал появляться и в некоторых встраиваемых системах, как правило, с использованием Node.js.

Система времени выполнения

Двигатель JavaScript должен быть встроен в среду выполнения (будь то веб-браузер или автономная система), чтобы предоставить объекты и методы, посредством которых скрипты могут взаимодействовать с внешней средой. Это включает в себя необходимые API для ввода-вывода, такие как сетевые операции, хранилище или графические возможности. Среда выполнения также обеспечивает возможность импорта скриптов. JavaScript – это однопоточный язык. Среда выполнения обрабатывает сообщения из очереди по одному, вызывая функцию, связанную с каждым новым сообщением, и создавая кадр стека вызовов с аргументами функции и локальными переменными. Стек вызовов расширяется и сжимается в зависимости от потребностей функции. Когда стек вызовов становится пустым после завершения функции, JavaScript переходит к следующему сообщению в очереди. Это называется циклом событий, который описывается как "выполнение до завершения", поскольку каждое сообщение полностью обрабатывается перед тем, как будет рассмотрено следующее. Однако модель параллелизма языка описывает цикл событий как неблокирующий: операции ввода-вывода программы выполняются с использованием событий и функций обратного вызова. Это означает, например, что JavaScript может обрабатывать щелчок мыши, ожидая возврата информации из запроса к базе данных. Известными автономными средами выполнения являются Node.js, Deno и Bun.

Особенности

Следующие возможности присущи всем соответствующим реализациям ECMAScript, если не указано обратное.

Императив и структурированный

JavaScript поддерживает значительную часть синтаксиса структурированного программирования из языка C (например, операторы if, циклы while, операторы switch, циклы do-while и т. д.). Частичным исключением является область видимости: изначально в JavaScript была только область видимости функций с использованием var; область видимости блоков была добавлена в ECMAScript 2015 с ключевыми словами let и const. Как и в C, JavaScript различает выражения и операторы. Одним из синтаксических отличий от C является автоматическая расстановка точек с запятой, позволяющая опускать точки с запятой (которые завершают операторы).

Оценка времени выполнения

JavaScript включает функцию eval, которая может выполнять операторы, переданные в виде строк во время выполнения.

Прототипы

JavaScript использует прототипы там, где многие другие объектно-ориентированные языки используют классы для наследования. В JavaScript возможно имитировать многие возможности, основанные на классах, с помощью прототипов.

Функции как конструкторы объектов

Функции выполняют роль конструкторов объектов, помимо своей обычной функции. Вызов функции с префиксом `new` создаст экземпляр прототипа, наследуя свойства и методы от конструктора (включая свойства прототипа Object). ECMAScript 5 предоставляет метод `Object.create`, позволяющий явно создать экземпляр без автоматического наследования от прототипа Object (в устаревших средах можно присвоить прототипу значение `null`). Свойство `prototype` конструктора определяет объект, используемый в качестве внутреннего прототипа для нового объекта. Новые методы можно добавить, изменяя прототип функции, используемой в качестве конструктора. Встроенные конструкторы JavaScript, такие как `Array` или `Object`, также имеют прототипы, которые можно модифицировать. Хотя модификация прототипа `Object` возможна, это обычно считается плохой практикой, поскольку большинство объектов в JavaScript наследуют методы и свойства от прототипа `Object`, и они могут не предполагать изменения прототипа.

Функции как методы

В отличие от многих объектно-ориентированных языков, в JavaScript нет различия между определением функции и определением метода. Различие возникает при вызове функции. Когда функция вызывается как метод объекта, ключевое слово `this` внутри функции привязывается к этому объекту для данного вызова.

Функциональные

Функции JavaScript являются объектами первого класса; функция рассматривается как объект. Следовательно, функция может иметь свойства и методы, такие как `call` и `bind`.

Лексическое замыкание

Вложенная функция — это функция, определенная внутри другой функции. Она создается каждый раз, когда вызывается внешняя функция. Кроме того, каждая вложенная функция формирует лексическое замыкание: лексическая область видимости внешней функции (включая любые константы, локальные переменные или значения аргументов) становится частью внутреннего состояния каждого объекта внутренней функции, даже после завершения выполнения внешней функции.

Анонимная функция

JavaScript также поддерживает анонимные функции.

Делегированный

JavaScript поддерживает неявную и явную делегацию.

Функции как роли (Особенности и Миксины)

JavaScript изначально поддерживает различные реализации паттернов ролей на основе функций, такие как Traits и Mixins. Такая функция определяет дополнительное поведение как минимум одним методом, привязанным к ключевому слову `this` внутри тела функции. Роль затем должна быть явно делегирована объектам, которым требуется дополнительное поведение, не передающееся по цепочке прототипов, с помощью вызова или применения (`call` или `apply`).

Состав и наследование объекта

В то время как явное делегирование на основе функций охватывает композицию в JavaScript, неявное делегирование происходит каждый раз, когда происходит обход прототипной цепочки для поиска, например, метода, который может быть связан с объектом, но не является его непосредственным свойством. Как только метод найден, он вызывается в контексте этого объекта. Таким образом, наследование в JavaScript обеспечивается автоматизмом делегирования, привязанным к свойству прототипа конструкторских функций.

Нулевая нумерация

JavaScript - это язык с нулевой индексацией.

Вариадические функции

Неопределенное количество параметров может быть передано функции. Функция может получить к ним доступ через формальные параметры и через локальный объект аргументов. Вариативные функции также можно создавать с помощью метода bind.

Литералы массива и объекта

Как и во многих скриптовых языках, массивы и объекты (ассоциативные массивы в других языках) можно создавать с помощью лаконичного сокращенного синтаксиса. Фактически, эти литералы лежат в основе формата данных JSON.

Регулярные выражения

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

Обещания и асинхронность/ожидание

JavaScript поддерживает промисы и Async/await для обработки асинхронных операций.

Обещания

Встроенный объект Promise предоставляет функциональность для работы с промисами и связывания обработчиков с окончательным результатом асинхронной операции. Недавно спецификация JavaScript представила методы-комбинаторы, которые позволяют разработчикам объединять несколько промисов JavaScript и выполнять операции в зависимости от различных сценариев. Представленные методы: Promise.race, Promise.all, Promise.allSettled и Promise.any.

Асинхронное соединение / ожидание

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

Безопасность

JavaScript и DOM предоставляют злоумышленникам возможность доставлять скрипты для выполнения на клиентском компьютере через Интернет. Разработчики браузеров минимизируют этот риск, используя два ограничения. Во-первых, скрипты выполняются в изолированной среде (песочнице), где они могут выполнять только действия, связанные с веб-технологиями, а не задачи общего назначения, такие как создание файлов. Во-вторых, скрипты ограничены политикой одного источника: скрипты с одного веб-сайта не имеют доступа к информации, такой как имена пользователей, пароли или cookie, отправленные на другой сайт. Большинство уязвимостей в безопасности, связанных с JavaScript, являются следствием нарушения либо политики одного источника, либо изолированной среды. Существуют подмножества JavaScript – ADsafe и Secure ECMAScript (SES), – обеспечивающие более высокий уровень безопасности, особенно для кода, созданного третьими сторонами (например, рекламой). Closure Toolkit – еще один проект, предназначенный для безопасного встраивания и изоляции стороннего JavaScript и HTML. Политика безопасности контента (Content Security Policy) является основным механизмом обеспечения выполнения на веб-странице только доверенного кода.

Скриптовый код для различных сайтов

Одной из распространенных проблем безопасности, связанных с JavaScript, является межсайтовый скриптинг (XSS) – нарушение политики одного источника. Уязвимости XSS возникают, когда злоумышленник может заставить целевой веб-сайт, например, сайт онлайн-банкинга, включить вредоносный скрипт в веб-страницу, отображаемую жертве. Этот скрипт может получить доступ к банковскому приложению с правами жертвы, потенциально раскрывая конфиденциальную информацию или осуществляя перевод средств без ее разрешения. Важным решением для устранения уязвимостей XSS является санитаризация HTML. Некоторые браузеры обеспечивают частичную защиту от отраженных XSS-атак, когда злоумышленник предоставляет URL-адрес, содержащий вредоносный скрипт. Однако даже пользователи этих браузеров уязвимы для других XSS-атак, например, когда вредоносный код хранится в базе данных. Полностью предотвратить XSS можно только при правильной разработке веб-приложений на стороне сервера. Уязвимости XSS также могут возникать из-за ошибок реализации со стороны разработчиков браузеров.

Подделка запросов с использованием различных сайтов

Еще одна межсайтовая уязвимость — подделка межсайтовых запросов (CSRF). При CSRF код на сайте злоумышленника обманывает браузер жертвы, заставляя его выполнять действия, которые пользователь не намеревался выполнять на целевом сайте (например, перевод денег в банке). Если целевые сайты полагаются исключительно на cookie для аутентификации запросов, запросы, инициированные кодом на сайте злоумышленника, могут содержать те же действительные учетные данные для входа, что и у пользователя, инициировавшего запрос. В общем случае, решение проблемы CSRF заключается в требовании значения аутентификации в скрытом поле формы, а не только в cookie, для аутентификации любого запроса, который может иметь длительные последствия. Проверка заголовка HTTP Referrer также может помочь. «Угон JavaScript» — это тип атаки CSRF, при котором тег <script> на сайте злоумышленника использует страницу на сайте жертвы, возвращающую конфиденциальную информацию, такую как JSON или JavaScript. Возможные решения включают:

требование токена аутентификации в параметрах POST и GET для любого ответа, возвращающего конфиденциальную информацию.

Неуместное доверие к клиенту

Разработчики клиент-серверных приложений должны осознавать, что ненадежным клиентам могут управлять злоумышленники. Автор приложения не может исходить из того, что его код JavaScript будет выполняться должным образом (или вообще), поскольку любой секрет, встроенный в код, может быть извлечен злоумышленником, обладающим достаточной настойчивостью. Это влечет за собой следующие последствия: Авторы веб-сайтов не могут полностью скрыть логику работы своего JavaScript, так как исходный код необходимо отправлять клиенту. Код можно обфусцировать, но обфускация поддается реверс-инжинирингу. Валидация форм на JavaScript предоставляет лишь удобство для пользователей, но не обеспечивает безопасность. Если сайт проверяет согласие пользователя с условиями обслуживания или фильтрует недопустимые символы из полей, предназначенных только для чисел, он должен выполнять эти проверки на сервере, а не только на клиенте. Скрипты могут быть выборочно отключены, поэтому нельзя полагаться на JavaScript для предотвращения таких действий, как сохранение изображения с помощью контекстного меню. Встраивание конфиденциальной информации, такой как пароли, в JavaScript считается крайне нежелательной практикой, поскольку она может быть извлечена злоумышленником. Загрязнение прототипа – это уязвимость, возникающая во время выполнения, позволяющая злоумышленникам перезаписывать произвольные свойства в прототипе объекта.

Неуместное доверие к разработчикам

Системы управления пакетами, такие как npm и Bower, популярны среди JavaScript-разработчиков. Эти системы позволяют разработчикам легко управлять зависимостями своих программ от программных библиотек, созданных другими разработчиками. Разработчики доверяют сопровождающим библиотеки в обеспечении их безопасности и актуальности, однако это не всегда оправдано. Эта слепая вера привела к появлению уязвимостей. Библиотеки, от которых зависят программы, могут получать новые релизы, вызывающие ошибки или уязвимости во всех зависимых программах. В то же время, библиотеки могут оставаться без обновлений, содержа известных уязвимостей, находящихся в открытом доступе. В исследовании, охватившем выборку из 133 000 веб-сайтов, было обнаружено, что 37% веб-сайтов используют библиотеки с как минимум одной известной уязвимостью. "Медианная задержка между самой старой версией библиотеки, используемой на каждом веб-сайте, и самой новой доступной версией этой библиотеки составляет 1177 дней в ALEXA, а разработка некоторых библиотек, которые все еще активно используются, прекращена несколько лет назад."

Ошибки кодирования браузера и плагина

JavaScript предоставляет интерфейс к широкому спектру возможностей браузера, некоторые из которых могут содержать уязвимости, такие как переполнение буфера. Эти уязвимости могут позволить злоумышленникам создавать сценарии, которые выполняют любой код по их желанию на компьютере пользователя. Этот код ни в коем случае не ограничивается другим JavaScript-приложением. Например, эксплуатация переполнения буфера может предоставить злоумышленнику доступ к API операционной системы с правами суперпользователя. Эти уязвимости затрагивали основные браузеры, включая Firefox, Internet Explorer и Safari. Плагины, такие как видеоплееры, Adobe Flash и широкий спектр элементов управления ActiveX, включенных по умолчанию в Microsoft Internet Explorer, также могут содержать уязвимости, которые можно использовать через JavaScript (подобные уязвимости использовались в прошлом). В Windows Vista Microsoft предприняла попытку снизить риски, связанные с такими ошибками, как переполнение буфера, запуская процесс Internet Explorer с ограниченными правами. Google Chrome аналогичным образом изолирует свои движки рендеринга страниц в собственной "песочнице".

Ошибки внедрения песочницы

Веб-браузеры способны выполнять JavaScript за пределами изолированной среды (песочницы), с правами доступа, необходимыми, например, для создания или удаления файлов. Такие права не предназначены для кода, загружаемого из сети. Некорректное предоставление прав доступа JavaScript из сети сыграло роль в уязвимостях в браузерах Internet Explorer и Firefox. В Windows XP Service Pack 2 компания Microsoft снизила уровень привилегий JScript в Internet Explorer. Microsoft Windows позволяет запускать исходные файлы JavaScript, расположенные на жестком диске компьютера, как обычные программы, не работающие в песочнице (см. Windows Script Host). Это делает JavaScript (как и VBScript) теоретически возможным каналом для распространения троянских программ, хотя трояны, написанные на JavaScript, встречаются нечасто на практике.

Хардверовая уязвимость

В 2015 году в научной работе исследователей в области безопасности была описана демонстрация концепции атаки Rowhammer, реализованная на JavaScript. В 2017 году была продемонстрирована атака на основе JavaScript, осуществляемая через браузер, способная обходить ASLR. Она получила название "ASLR⊕Cache" или AnC. В 2018 году в работе, представившей атаки Spectre, направленные на спекулятивное исполнение в процессорах Intel и других производителей, была включена реализация на JavaScript.

Инструменты развития

Важные инструменты развивались вместе с языком. Каждый крупный веб-браузер имеет встроенные инструменты веб-разработки, включая отладчик JavaScript. Инструменты статического анализа программ, такие как ESLint и JSLint, сканируют код JavaScript на соответствие набору стандартов и рекомендаций. Некоторые браузеры имеют встроенные профилировщики. Также были созданы отдельные библиотеки профилирования, такие как benchmark.js и jsbench. Многие текстовые редакторы поддерживают подсветку синтаксиса кода JavaScript.

Ява

Распространенное заблуждение заключается в том, что JavaScript напрямую связан с Java. Оба языка действительно имеют синтаксис, похожий на C (язык C является их ближайшим общим языком-предком). Они также обычно выполняются в изолированной среде (песочнице), и JavaScript был разработан с учетом синтаксиса и стандартной библиотеки Java. В частности, все ключевые слова Java были зарезервированы в оригинальном JavaScript, стандартная библиотека JavaScript следует соглашениям об именах Java, а объекты и массивы JavaScript основаны на классах из Java 1.0. Оба языка впервые появились в 1995 году, но Java был разработан Джеймсом Гослингом из Sun Microsystems, а JavaScript – Бренданом Айхом из Netscape Communications. Различия между этими двумя языками более существенны, чем их сходства. Java использует статическую типизацию, в то время как типизация JavaScript – динамическая. Java загружается из скомпилированного байт-кода, а JavaScript – как исходный код, читаемый человеком. Объекты Java основаны на классах, а объекты JavaScript – на прототипах. Наконец, Java не поддерживала функциональное программирование до версии Java 8, в то время как JavaScript поддерживал его с самого начала, находясь под влиянием Scheme.

JSON

JSON — это формат данных, основанный на JavaScript, отсюда и название JavaScript Object Notation. Это широко используемый формат, поддерживаемый многими другими языками программирования.

Транспилеры

Многие веб-сайты активно используют JavaScript, поэтому для преобразования кода, написанного на других языках, были разработаны транспиляторы, что может упростить процесс разработки. TypeScript и CoffeeScript — два заметных языка, которые преобразуются в JavaScript.

WebAssembly (сборка веб-сайтов)

WebAssembly — более новый язык с байт-кодовым форматом, разработанный для дополнения JavaScript, особенно тех частей веб-скриптов, которые критичны к производительности. Все основные движки JavaScript поддерживают WebAssembly, который выполняется в той же среде безопасности (песочнице), что и обычный JavaScript-код. asm.js — это подмножество JavaScript, которое послужило предшественником WebAssembly.