| JavaScript: тип Reference Record, обзор |
|
| Добавил(а) microsin | |||||||||||||||
|
Reference Record (запись ссылки) — это внутренний тип данных в спецификации ECMAScript, который используется для объяснения поведения таких операторов, как delete, typeof, операторов присваивания, ключевого слова super и других языковых конструкций. Например, левый операнд присваивания должен выдавать Reference Record. Простыми словами, Reference Record — это промежуточная структура, которая описывает "к чему мы обращаемся" и "как к этому обращаться" до того, как значение будет фактически прочитано или записано. Она связывает имя (или выражение) с местом, где хранится значение. [Поля (Fields) Reference Record] Согласно спецификации, Reference Record состоит из четырёх полей:
[Классификация ссылок] Спецификация определяет несколько абстрактных операций для проверки типа Reference Record: • IsUnresolvableReference: [[Base]] равен `~unresolvable~`. [Как это работает: GetValue и PutValue] Основное назначение Reference Record — передаваться в абстрактные операции `GetValue` (для чтения) и `PutValue` (для записи), которые определяют, как именно получить или изменить значение. Логика `GetValue(V)`: 1. Если `V` — не Reference Record, то вернуть `V` как есть (это просто значение). 2. Если `V` — unresolvable reference, то выбросить `ReferenceError`. 3. Если это ссылка на свойство (IsPropertyReference), то получить базовый объект и вызвать его внутренний метод [[Get]], передав [[ReferencedName]] и правильное this (которое для super будет [[ThisValue]]). 4. Если это ссылка на окружение (Identifier), то вызвать `GetBindingValue` у соответствующей Environment Record. Логика `PutValue(V, W)`: аналогична, но с записью: unresolvable reference в строгом режиме выбрасывает `ReferenceError`, ссылка на свойство вызывает [[Set]], а ссылка на окружение — SetMutableBinding. [Зачем это нужно?] Reference Record — это спецификационный приём, а не доступная программисту конструкция. Он позволяет точно описать разницу между семантикой работы с переменными (хранящимися в Environment Record) и свойствами объектов. Без этой абстракции было бы сложно объяснить, почему `delete obj.prop` и `delete varName` работают по-разному, или почему `super.method()` корректно находит метод в прототипе. Важно отметить, что реализация движками JavaScript не обязана создавать объект Reference Record для каждого обращения. Спецификация прямо указывает, что объект, который может быть создан в ходе `GetValue`/`PutValue`, недоступен за пределами этих операций, и реализация может избежать его фактического создания. |