ECMAScript | Обзор ECMAScript

ECMAScript | Обзор ECMAScript

Ниже приводится неофициальный обзор 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: Отношения объект / прототип

Рисунок 1 - Отношения объект/прототип - ECMAScript
Рисунок 1 — Отношения объект/прототип — ECMAScript

неявная ссылка на прототип (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, как определено в этой спецификации. Кроме того, реализация должна поддерживать комбинацию исходных текстовых единиц неограниченного и строгого режима в единую составную программу.

 

Информационные ссылки

ECMAScript | Обзор

Стандарт ECMAScript — Раздел «4 Overview» — https://tc39.es/ecma262/#sec-overview

Стандарт ECMAScript — Раздел «4.3 ECMAScript Overview» — https://tc39.es/ecma262/#sec-ecmascript-overview