Почему переменный объект был изменен на лексическое окружение в ES5?
ES5 изменил переменный объект(VO) на лексическую среду. Какова мотивация такого изменения, поскольку ВО уже очень очевидно, как восприятие?
2 ответа
Я думаю, что переменные объекты больше похожи на записи окружения.
Запись среды записывает привязки идентификаторов, которые создаются в рамках связанной с ним лексической среды.
В ES5 есть два разных типа записей среды:
Декларативные записи среды используются для определения влияния синтаксических элементов языка ECMAScript, таких как функции FunctionDeclarations, VariableDeclarations и Catch, которые напрямую связывают привязки идентификаторов со значениями языка ECMAScript. Записи объектной среды используются для определения влияния элементов ECMAScript, таких как Program и WithStatement, которые связывают привязки идентификаторов со свойствами некоторого объекта.
Таким образом, вопрос заключается в том, почему декларативные записи среды были введены вместо использования только записей объектной среды, подобно переменным объектам ES3. Разница в том, что декларативные записи среды могут иметь неизменные привязки:
В дополнение к изменяемым привязкам, поддерживаемым всеми записями среды, декларативные записи среды также обеспечивают неизменяемые привязки. Неизменная привязка - это та, где связь между идентификатором и значением не может быть изменена после того, как она была установлена.
Неизменяемые привязки не имеют прямого эквивалента в объектах. Свойство может быть определено как неконфигурируемое и недоступное для записи, становясь неизменным. Тем не мение,
Создание и инициализация неизменяемого связывания - это отдельные этапы, поэтому такие связывания могут существовать либо в инициализированном, либо в неинициализированном состоянии.
Но вы не можете иметь неинициализированное свойство. Если вы определяете неконфигурируемое недоступное для записи свойство со значением undefined, вы не сможете инициализировать его до желаемого значения.
Я не думаю, что возможно иметь неинициализированные неизменяемые привязки в ES5. CreateImmutableBinding используется только в объявлении привязки объявления и определении функции, и в обоих случаях он немедленно инициализируется с помощью InitializeImmutableBinding.
Но, возможно, это было сделано, чтобы разрешить неинициализированные неизменяемые привязки как расширения языка, такие как JavaScript 1.5 const
, Или, может быть, они уже имели в виду ES6 const
,
Тот же автор, чью статью о ES3 вы связали, писал также о ES5 (и даже связывал этот раздел там). Я процитирую г-на Сошникова из его раздела "Декларация декларативной среды" в ECMA-262-5 подробно. Глава 3.2. Лексические среды: реализация ECMAScript:
В общем случае предполагается, что привязки декларативных записей хранятся непосредственно на низком уровне реализации (например, в регистрах виртуальной машины, что обеспечивает быстрый доступ). Это основное отличие от старой концепции объекта активации, используемой в ES3.
То есть спецификация не требует (и даже косвенно не рекомендует) реализовывать декларативные записи как простые объекты, которые в этом случае неэффективны. Следствием этого факта является то, что декларативные записи среды не предполагаются открытыми непосредственно для уровня пользователя, что означает, что мы не можем получить доступ к этим привязкам, например, к свойствам записи. На самом деле, мы не могли и раньше, даже в ES3 - там объект активации также был недоступен непосредственно пользователю (за исключением того, что реализация Rhino, тем не менее, выявила его через
__parent__
имущество).Потенциально декларативные записи позволяют использовать полную лексическую технику адресации, то есть получить прямой доступ к необходимым переменным без какого-либо поиска в цепочке областей - независимо от глубины вложенной области (если хранилище является фиксированным и неизменным, все адреса переменных могут быть известны даже во время компиляции). Однако в спецификации ES5 этот факт не упоминается напрямую.
Итак, еще раз, главное, что мы должны понять, почему нужно было заменить старую концепцию объекта активации декларативной записью среды, это прежде всего эффективность реализации.
Таким образом, как упомянул Брендан Айх (последний абзац), реализация объекта активации в ES3 была просто "ошибкой": "Я отмечу, что в ES5 есть некоторые реальные улучшения, в частности в главе 10, которая теперь использует среды декларативного связывания, Злоупотребление ES1-3 объектами для областей (опять же я виноват в том, что сделал это в JS в 1995 году, экономя на объектах, необходимых для быстрой реализации языка), было ошибкой, а не функцией ".
Я не думаю, что мог бы выразить это лучше.