Где расположены аргументы в лексической среде?

#javascript #parameters #scope #language-lawyer

Вопрос:

Следующий код всегда выводит аргумент , переданный параметру a , независимо от наличия переменной с тем же именем.

Предположительно, потому, что идентификаторы параметров привязаны отдельно к переменным в области видимости. Где они расположены? Находятся ли они в лексической среде?

 function foo(a, b = () => a) {
  var a = 1
  console.log(b())
}
foo() // undefined
foo(2) // 2 

Является ли это тем, что var объявления попадают в специальную переменную среду, в то время как параметры располагаются в лексической среде? И let и const избежать конфликта, сделав переопределение ранней ошибкой?

Уместно также:

Комментарии:

1.Список параметров, как я понимаю, имеет свою собственную область действия. Закрытие для этой => функции имеет параметр a в области действия.

2. Я думаю, что это часть статической семантики . «Связанные имена» из списка параметров добавляются в набор для следующего параметра в списке формальных параметров. Однако я не на 100% уверен, что смотрю на правильную вещь, потому что я только наполовину выпил чашку кофе.

3. Конечно, все становится намного сложнее, когда вы рассматриваете синтаксис деструкции в списке параметров, но это похоже на то, что слева направо для каждой позиции привязки в списке формальных параметров появляется новая лексическая область, а область действия функции-это еще один лексический слой.

4. Иногда это помогает подтвердить ожидаемое поведение различных взаимодействующих семантик, просто поместив их в babel и посмотрев на вывод ES5, о котором обычно легче рассуждать. Но чтобы объяснить мой предыдущий комментарий, используйте let вместо var генерирует a SyntaxError , что я нахожу гораздо предпочтительнее var , чем приведенное выше неявное затенение записи среды списка параметров.

5. @52d6c6af эта семантика на самом деле не соотносится один к одному с наблюдаемыми объектами в языке. Нет, я не верю, что это связано с arguments объектом, так как поведение идентично при переходе foo на функцию со стрелкой.

Ответ №1:

В случае наличия любых значений по умолчанию для параметров создается отдельная запись среды.

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

ПРИМЕЧАНИЕ. Отдельная запись среды необходима для обеспечения того, чтобы замыкания, созданные выражениями в списке формальных параметров, не отображали объявления в теле функции.

Подробнее из спецификации:

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

Поэтому в отсутствие аргументов по умолчанию я делаю вывод, что для привязки параметров используется одна из ранее существовавших лексических сред (VariableEnvironment или LexicalEnvironment). Может быть.