В этом разделе содержится ненормативный обзор языка ECMAScript.
ECMAScript — это объектно-ориентированный язык программирования для выполнения вычислений и управления вычислительными объектами в среде хоста (host environment). ECMAScript, как здесь определено, не предназначен для вычислительной автономности; действительно, в этой спецификации нет положений для ввода внешних данных или вывода вычисленных результатов. Вместо этого ожидается, что вычислительная среда программы ECMAScript будет предоставлять не только объекты и другие средства, описанные в этой спецификации, но также и определенные объекты, зависящие от среды, описание и поведение которых выходят за рамки данной спецификации, за исключением указания того, что они могут предоставлять определенные свойства, к которым можно получить доступ, и определенные функции, которые можно вызывать из программы ECMAScript.
ECMAScript изначально был разработан для использования в качестве языка сценариев, но стал широко использоваться как язык программирования общего назначения. Язык сценариев (scripting language) — это язык программирования, который используется для управления, настройки и автоматизации средств существующей системы. В таких системах полезные функциональные возможности уже доступны через пользовательский интерфейс, а язык сценариев является механизмом для предоставления этих функциональных возможностей программному управлению. Таким образом, существующая система, как говорят, обеспечивает среду хоста объектов и средств, которая дополняет возможности языка сценариев. Язык сценариев предназначен для использования как профессиональными, так и непрофессиональными программистами.
ECMAScript изначально разрабатывался как язык веб-сценариев (Web scripting language), предоставляющий механизм для оживления веб-страниц в браузерах и выполнения серверных вычислений как части клиент-серверной веб-архитектуры. ECMAScript теперь используется для предоставления основных возможностей написания сценариев для различных сред хоста. Поэтому основной язык указан в этом документе отдельно от любой конкретной среды хоста.
Использование ECMAScript вышло за рамки простого написания сценариев и теперь используется для всего спектра задач программирования во многих различных средах и масштабах. По мере расширения использования ECMAScript расширяются возможности и возможности, которые он предоставляет. ECMAScript теперь является полнофункциональным языком программирования общего назначения.
Веб-скрипты (Web Scripting — пункт 4.1)
Веб-браузер (web browser) предоставляет среду хоста ECMAScript для вычислений на стороне клиента, включая, например, объекты, которые представляют окна (windows), меню (menus), всплывающие окна (pop-ups), диалоговые окна (dialog boxes), текстовые области (text areas), привязки (anchors), фреймы (frames), историю (history), файлы cookie (cookies) и ввод/вывод (input/output). Кроме того, среда хоста предоставляет средства для присоединения кода сценария к таким событиям, как изменение фокуса (change of focus), загрузка страницы и изображения (page and image loading), выгрузка (unloading), ошибка и прерывание (error and abort), выбор (selection), отправка формы (form submission) и действия мыши (mouse actions). Код сценария появляется в HTML, а отображаемая страница представляет собой комбинацию элементов пользовательского интерфейса, фиксированного и вычисленного текста и изображений. Код сценария реагирует на взаимодействие с пользователем, и нет необходимости в основной программе.
Веб-сервер (web server) предоставляет другую среду хоста для вычислений на стороне сервера, включая объекты представления запросов (requests), клиентов (clients) и файлов (files); и механизмов для блокировки и обмена данными (lock and share data). Совместное использование сценариев на стороне браузера и на стороне сервера позволяет распределять вычисления между клиентом и сервером, обеспечивая при этом настраиваемый пользовательский интерфейс для веб-приложения (Web-based application).
Каждый веб-браузер и сервер, поддерживающий ECMAScript, предоставляет свою собственную среду хоста, завершая среду выполнения ECMAScript.
Хосты и Реализации (Hosts and Implementations — пункт 4.2)
Чтобы облегчить интеграцию ECMAScript в среду хоста, эта спецификация переносит определение определенных средств (например, абстрактных операций), полностью или частично, на источник за пределами этой спецификации. Редакционно эта спецификация различает следующие виды отсрочек.
Реализация (implementation) — это внешний источник, который дополнительно определяет средства, перечисленные в Приложении D, или те, которые помечены как определяемые реализацией (implementation-defined) или приближенные к реализации (implementation-approximated). В неформальном использовании под реализацией понимается конкретный артефакт, такой как конкретный веб-браузер (web browser).
Определяемое реализацией средство (implementation-defined facility) — это средство, которое откладывает свое определение до внешнего источника без дополнительных уточнений. Эта спецификация не дает никаких рекомендаций для конкретного поведения, и соответствующие реализации могут свободно выбирать любое поведение в рамках ограничений, установленных данной спецификацией.
Средство, приближенное к реализации (implementation-approximated facility) — это средство, которое откладывает свое определение до внешнего источника, рекомендуя при этом идеальное поведение. Хотя соответствующие реализации могут свободно выбирать любое поведение в рамках ограничений, установленных данной спецификацией, им рекомендуется стремиться приблизиться к идеалу. Некоторые математические операции, такие как Math.exp, аппроксимируются реализацией.
Хост (host) — это внешний источник, который дополнительно определяет средства, перечисленные в Приложении D, но не дополнительно определяет другие средства, определяемые реализацией или приближенные к реализации. В неформальном использовании хостом называется набор всех реализаций, таких как набор всех веб-браузеров, которые взаимодействуют с этой спецификацией таким же образом через Приложение D. Хост часто является внешней спецификацией, такой как WHATWG HTML (https : //html.spec.whatwg.org/). Другими словами, средства, определяемые хостом (host-defined), часто дополнительно определяются во внешних спецификациях.
Крюк хоста (host hook) — это абстрактная операция, которая полностью или частично определяется внешним источником. Все крюки хоста должны быть перечислены в Приложении D.
Определяемое хостом средство (host-defined facility) — это средство, определение которого передается внешнему источнику без дополнительной квалификации, и оно перечислено в Приложении D. Реализации, которые не являются хостами, также могут предоставлять определения для определяемых средств хоста.
Среда хоста (host environment) — это частный выбор определения для всех определяемых хостом средств. Среда хоста обычно включает в себя объекты или функции, которые позволяют получать ввод и предоставлять вывод в виде определяемых хостом свойств глобального объекта.
Эта спецификация следует редакционному соглашению о том, что всегда используются наиболее конкретные термины. Например, если средство определяется хостом (host-defined), его не следует называть определяемым реализацией (implementation-defined).
И хосты, и реализации могут взаимодействовать с этой спецификацией через типы языка, типы спецификаций, абстрактные операции, грамматические конструкции, внутренние объекты и внутренние символы, определенные здесь.
Обзор ECMAScript (ECMAScript Overview — пункт 4.3)
Ниже приводится неофициальный обзор ECMAScript — описаны не все части языка. Этот обзор не является частью стандарта.
ECMAScript основан на объектах: базовый язык и возможности хоста предоставляются объектами, а программа ECMAScript представляет собой кластер взаимодействующих объектов. В ECMAScript объект (object) представляет собой набор из нуля или более свойств (properties), каждое из которых имеет атрибуты (attributes), определяющие, как каждое свойство может использоваться, например, когда для атрибута Writable для свойства установлено значение false, любая попытка выполненного кода ECMAScript назначить другое значение свойства не удается.
Свойства (properties) — это контейнеры, которые содержат другие объекты, примитивные значения (primitive values) или функции (functions).
Примитивное значение (primitive values) является членом одного из следующих встроенных типов: Undefined, Null, Boolean, Number, BigInt, String и Symbol; объект является членом встроенного типа (built-in type) Object; а функция — это вызываемый объект. Функция, связанная с объектом через свойство, называется методом (method).
ECMAScript определяет набор встроенных объектов (built-in objects), которые завершают определение сущностей ECMAScript. Эти встроенные объекты включают глобальный объект (global object); объекты, которые являются фундаментальными для семантики среды выполнения (runtime semantics) языка, включая Object, Function, Boolean, Symbol и различные объекты ошибок Error; объекты, представляющие числовые значения и управляющие ими, включая Math, Number и Date; объекты обработки текста String и RegExp; объекты, которые представляют собой индексированные коллекции значений, включая массивы Array и девять различных типов Типизированных Массивов (Typed Arrays), все элементы которых имеют определенное числовое представление данных; коллекции с ключами, включая объекты Map и Set; объекты, поддерживающие структурированные данные, включая объект JSON, ArrayBuffer, SharedArrayBuffer и DataView; объекты, поддерживающие абстракции управления, включая функции генератора и объекты Promise; и объекты отражения, включая Proxy и Reflect.
ECMAScript также определяет набор встроенных операторов (operators). Операторы ECMAScript включают в себя различные унарные операции, мультипликативные операторы, аддитивные операторы, операторы побитового сдвига, операторы отношения, операторы равенства, двоичные побитовые операторы, двоичные логические операторы, операторы присваивания и оператор запятой.
Большие программы ECMAScript поддерживаются модулями (modules), которые позволяют разделить программу на несколько последовательностей операторов и объявлений. Каждый модуль явно определяет используемые им объявления, которые должны быть предоставлены другими модулями, и какие из его объявлений доступны для использования другими модулями.
Синтаксис ECMAScript намеренно напоминает синтаксис Java. Синтаксис ECMAScript ослаблен, чтобы он мог служить простым в использовании языком сценариев. Например, не требуется, чтобы тип переменной был объявлен, а типы не были связаны со свойствами, а для определенных функций не требуется, чтобы их объявления отображались в текстовом виде перед вызовом к ним.
Объекты (Objects — пункт 4.3.1)
Несмотря на то, что ECMAScript включает синтаксис для определений классов, объекты ECMAScript принципиально не основаны на классах, как в C++, Smalltalk или Java. Вместо этого объекты могут быть созданы различными способами, в том числе через буквальную нотацию (via a literal notation) или через конструкторы (via constructors), которые создают объекты, а затем выполняют код, который инициализирует их все или часть, присваивая начальные значения их свойствам.
Каждый конструктор — это функция, имеющая свойство с именем "prototype"
(прототип), которое используется для реализации наследования на основе прототипов (prototype-based inheritance) и общих свойств (shared properties). Объекты создаются с помощью конструкторов в выражениях new
; например, new Date (2009, 11)
создает новый объект Date. Вызов конструктора без использования new
имеет последствия, которые зависят от конструктора. Например, Date() создает строковое представление текущей даты и времени, а не объект.
Каждый объект, созданный конструктором, имеет неявную ссылку (implicit reference) (называемую прототипом объекта (prototype)) на значение свойства "prototype"
его конструктора. Более того, прототип может иметь не-null неявную ссылку на свой прототип и так далее; это называется цепочкой прототипов (prototype chain). Когда делается ссылка на свойство в объекте, эта ссылка относится к свойству с этим именем в первом объекте в цепочке прототипов, который содержит свойство с этим именем. Другими словами, сначала непосредственно упомянутый объект исследуется на предмет наличия такого свойства; если этот объект содержит указанное свойство, это свойство, на которое ссылается ссылка; если этот объект не содержит названного свойства, следующим исследуется прототип этого объекта; и так далее.
Рисунок 1: Отношения объект / прототип
неявная ссылка на прототип (implicit prototype link)
явное свойство прототипа (explicit prototype property)
В объектно-ориентированном языке на основе классов, как правило, состояние передается экземплярами, методы передаются классами, а наследование касается только структуры и поведения. В ECMAScript состояние и методы передаются объектами, а структура, поведение и состояние наследуются.
Все объекты, которые напрямую не содержат конкретное свойство, содержащееся в их прототипе, разделяют это свойство и его значение. Рисунок 1 иллюстрирует это:
CF — это конструктор (а также объект). Пять объектов были созданы с использованием выражений new
: cf1, cf2, cf3, cf4 и cf5. Каждый из этих объектов содержит свойства с именами «q1» и «q2». Пунктирные линии представляют неявное отношение прототипа; так, например, прототипом cf3 является CFp. Конструктор CF имеет два свойства с именами «P1» и «P2», которые не видны для CFp, cf1, cf2, cf3, cf4 или cf5. Свойство с именем «CFP1» в CFp совместно используется cf1, cf2, cf3, cf4 и cf5 (но не CF), как и любые свойства в неявной цепочке прототипов CFp, которые не имеют имен «q1», «q2», или «CFP1». Обратите внимание, что между CF и CFp нет неявной связи прототипа.
В отличие от других объектных языков на основе классов, свойства можно добавить к объектам динамически, присваивая им значения. То есть конструкторы не требуют называть или присваивать значения всем или каким-либо свойствам сконструированного объекта. На приведенной выше диаграмме можно добавить новое общее свойство для cf1, cf2, cf3, cf4 и cf5, присвоить новое значение свойству в CFp.
Хотя объекты ECMAScript по своей сути не основаны на классах, часто бывает удобно определять абстракции, подобные классам, на основе общего шаблона функций конструктора, объектов-прототипов и методов. Сами встроенные объекты ECMAScript следуют такому шаблону, подобному классу. Начиная с ECMAScript 2015, язык ECMAScript включает определения синтаксических классов, которые позволяют программистам кратко определять объекты, соответствующие тому же шаблону абстракции, подобному классу, используемому встроенными объектами.
Строгий вариант ECMAScript (The Strict Variant of ECMAScript — пункт 4.3.1)
Язык ECMAScript признает возможность того, что некоторые пользователи языка могут захотеть ограничить использование некоторых функций, доступных на языке. Они могут делать это в интересах безопасности, чтобы избежать того, что они считают подверженными ошибкам функциями, чтобы получить расширенную проверку ошибок или по другим причинам по своему выбору. В поддержку этой возможности ECMAScript определяет строгий вариант языка. Строгий вариант языка исключает некоторые специфические синтаксические и семантические особенности обычного языка ECMAScript и изменяет детальную семантику некоторых функций. Строгий вариант также определяет дополнительные условия ошибки, о которых необходимо сообщать путем выдачи исключений ошибок в ситуациях, которые не определены как ошибки в нестрогой форме языка.
Строгий вариант ECMAScript обычно называют строгим режимом (strict mode) языка. Выбор строгого режима и использование синтаксиса и семантики строгого режима ECMAScript явно выполняется на уровне отдельных единиц исходного текста ECMAScript, как описано в 11.2.2. Поскольку строгий режим выбирается на уровне синтаксической единицы исходного текста, строгий режим накладывает только ограничения, которые имеют локальный эффект в пределах такой единицы исходного текста. Строгий режим не ограничивает и не изменяет какой-либо аспект семантики ECMAScript, который должен работать согласованно для нескольких исходных текстовых единиц. Полная программа на ECMAScript может состоять из блоков исходного текста ECMAScript как в строгом, так и в нестрогом режиме. В этом случае строгий режим применяется только при фактическом выполнении кода, определенного в исходном текстовом блоке строгого режима.
Чтобы соответствовать этой спецификации, реализация ECMAScript должна реализовывать как полный неограниченный язык ECMAScript, так и строгий вариант языка ECMAScript, как определено в этой спецификации. Кроме того, реализация должна поддерживать комбинацию исходных текстовых единиц неограниченного и строгого режима в единую составную программу.
Понятия и определения (Terms and Definitions- пункт 4.4)
Для целей этого документа применяются следующие термины и определения.
implementation-approximated
implementation-defined
host-defined
type
primitive value
object
constructor
prototype
ordinary object
exotic object
standard object
built-in object
undefined value
Undefined type
null value
Null type
Boolean value
Boolean type
Boolean object
String value
String type
String object
Number value
Number type
Number object
Infinity
NaN
BigInt value
BigInt type
BigInt object
Symbol value
Symbol type
Symbol object
function
built-in function
property
method
built-in method
attribute
own property
inherited property
4.4.1 implementation-approximated
Приближенное к реализации средство определяется полностью или частично внешним источником, но имеет рекомендованное идеальное поведение в этой спецификации
4.4.2 implementation-defined
Средство, определяемое реализацией, определяется полностью или частично внешним источником в этой спецификации
4.4.3 host-defined
То же, что и в зависимости от реализации
Редакционно смотри пункт 4.2.
4.4.4 type
Набор значений данных, как определено в разделе 6
4.4.5 primitive value
Член одного из типов Undefined, Null, Boolean, Number, BigInt, Symbol или String, как определено в разделе 6
Примитивное значение — это элемент данных, который представлен непосредственно на самом низком уровне реализации языка.
4.4.6 object
Член типа Object
Объект представляет собой набор свойств и имеет единственный объект-прототип. Прототипом может быть нулевое значение.
4.4.7 constructor
Функциональный объект, который создает и инициализирует объекты
Значение свойства "prototype"
конструктора — это объект-прототип, который используется для реализации наследования и общих свойств.
4.4.8 prototype
Объект, который предоставляет общие свойства для других объектов
Когда конструктор создает объект, этот объект неявно ссылается на свойство "prototype"
конструктора с целью разрешения ссылок на свойства. На свойство "prototype"
конструктора можно ссылаться с помощью программного выражения constructor.prototype
, а свойства, добавленные к прототипу объекта, совместно используются посредством наследования всеми объектами, использующими прототип. В качестве альтернативы новый объект может быть создан с явно указанным прототипом с помощью встроенной функции Object.create
.
4.4.9 ordinary object
Объект, который имеет поведение по умолчанию для основных внутренних методов, которые должны поддерживаться всеми объектами
4.4.10 exotic object
Объект, который не имеет поведения по умолчанию для одного или нескольких основных внутренних методов
Любой объект, который не является обычным объектом, является экзотическим объектом.
4.4.11 standard object
Объект, семантика которого определяется данной спецификацией
4.4.12 built-in object
Встроенный объект — это объект, указанный и предоставляемый реализацией ECMAScript
Стандартные встроенные объекты определены в этой спецификации. Реализация ECMAScript может определять и предоставлять дополнительные виды встроенных объектов. Встроенный конструктор (built-in constructor) — это встроенный объект, который также является конструктором.
4.4.13 undefined value
Примитивное значение, используемое, когда переменной не было присвоено значение
4.4.14 Undefined type
Тип, единственным значением которого является неопределенное значение — undefined
4.4.15 null value
Примитивное значение, которое представляет преднамеренное отсутствие какого-либо значения объекта
4.4.16 Null type
Тип, единственным значением которого является null значение
4.4.17 Boolean value
Член логического типа Boolean
Есть только два логических значения: true(истина) и false(ложь).
4.4.18 Boolean type
Тип, состоящий из примитивных значений true и false
4.4.19 Boolean object
Член типа Object, который является экземпляром стандартного встроенного логического Boolean конструктора
Логический (Boolean) объект создается с помощью логического конструктора в новом выражении new
, предоставляя логическое значение в качестве аргумента. Результирующий объект имеет внутренний слот, значением которого является логическое значение. Логический объект может быть приведен к логическому значению.
4.4.20 String value
Примитивное значение, которое представляет собой конечную упорядоченную последовательность из нуля или более 16-битных целочисленных значений без знака
Значение String является членом типа String. Каждое целочисленное значение в последовательности обычно представляет собой одну 16-битную единицу текста UTF-16. Однако ECMAScript не накладывает никаких ограничений или требований на значения, за исключением того, что они должны быть 16-битными целыми числами без знака.
4.4.21 String type
Набор всех возможных значений String
4.4.22 String object
Член типа Object, который является экземпляром стандартного встроенного конструктора String
Объект String создается с помощью конструктора String в новом выражении new
, передавая значение String в качестве аргумента. Результирующий объект имеет внутренний слот, значением которого является значение String. Объект String может быть приведен к значению String путем вызова конструктора String как функции (22.1.1.1).
4.4.23 Number value
Примитивное значение, соответствующее значению IEEE 754-2019 в 64-битном двоичном формате двойной точности
Числовое значение является членом числового типа и является прямым представлением числа.
4.4.24 Number type
Набор всех возможных числовых значений, включая специальное значение «Not-a-Number» (NaN), положительную бесконечность и отрицательную бесконечность
4.4.25 Number object
Член типа Object, который является экземпляром стандартного встроенного конструктора Number
Объект Number создается с помощью конструктора Number в новом выражении new
, передавая значение Number в качестве аргумента. Результирующий объект имеет внутренний слот, значением которого является значение Number. Объект Number может быть приведен к значению Number путем вызова конструктора Number как функции (21.1.1.1).
4.4.26 Infinity
Числовое значение, которое является положительным бесконечным числовым значением
4.4.27 NaN
Числовое значение, которое является значением IEEE 754-2019 «Not-a-Number».
4.4.28 BigInt value
Примитивное значение, соответствующее целочисленному значению произвольной точности
4.4.29 BigInt type
Набор всех возможных значений BigInt
4.4.30 BigInt object
Член типа Object, являющийся экземпляром стандартного встроенного конструктора BigInt
4.4.31 Symbol value
Примитивное значение, представляющее уникальный ключ свойства не String Object
4.4.32 Symbol type
Набор всех возможных значений символов
4.4.33 Symbol object
Член типа Object, который является экземпляром стандартного встроенного конструктора Symbol
4.4.34 function
Член типа Object, который может быть вызван как подпрограмма
Помимо свойств, функция содержит исполняемый код и состояние, определяющие ее поведение при вызове. Код функции может быть написан или не написан на ECMAScript.
4.4.35 built-in function
Встроенный объект, который является функцией
Примеры встроенных функций включают parseInt
и Math.exp
. Хост или реализация могут предоставлять дополнительные встроенные функции, которые не описаны в этой спецификации.
4.4.36 property
Часть объекта, которая связывает ключ (либо строковое значение String, либо значение символа Symbol) и значение
В зависимости от формы свойства значение может быть представлено либо непосредственно как значение данных (примитивное значение, объект или объект функции), либо косвенно парой функций доступа.
4.4.37 method
Функция, которая является значением свойства
Когда функция вызывается как метод объекта, объект передается функции как значение this.
4.4.38 built-in method
Метод, который является встроенной функцией
Стандартные встроенные методы определены в этой спецификации. Хост или реализация могут предоставлять дополнительные встроенные методы, которые не описаны в этой спецификации.
4.4.39 attribute
Внутреннее значение, определяющее некоторую характеристику свойства
4.4.40 own property
Свойство, которое непосредственно содержится в его объекте
4.4.41 inherited property
Свойство объекта, которое не является собственным свойством, но является свойством (собственным или унаследованным) прототипа объекта
Организация данной спецификации (Organization of This Specification — пункт 4.5)
Остальная часть этой спецификации организована следующим образом:
В разделе 5 определены условные обозначения, используемые в спецификации.
В разделах с 6 по 10 определяется среда выполнения, в которой работают программы ECMAScript.
Разделы с 11 по 17 определяют фактический язык программирования ECMAScript, включая его синтаксическую кодировку и семантику выполнения всех функций языка.
Разделы с 18 по 28 определяют стандартную библиотеку ECMAScript. Они включают определения всех стандартных объектов, доступных для использования программами ECMAScript по мере их выполнения.
В разделе 29 описывается модель согласованности памяти для доступа к памяти, поддерживаемой SharedArrayBuffer, и методов объекта Atomics.
Информационные ссылки
Стандарт ECMAScript — Раздел «4 Overview» — https://tc39.es/ecma262/#sec-overview