Содержит ли JS список параметров как область действия, которая может быть закрыта?

Глядя на этот простой код, который использует Lazy Expressions:

var x = 1;

function foo(x = 2, f = () => x) {
  var x = 5;
  console.log(f())
}

foo()

Ответ 1

Параметры функции имеют область действия.

В первом примере вы выделяете новую переменную x, поэтому она не перезаписывается:

//Global x
var x = 1;

function foo(x = 2 /* Local scope x */ , f = () => x /* Local scope x bound to new function scope */ ) {
  /* new local scope x. If you removed the "var", this would overwrite localscope x */
  var x = 5;
  /* All 3 x accessed */
  console.log(f(), x, window.x)
}

foo()

Ответ 2

Это интересный вопрос.

Лучше всего отнести спецификации Ecmascript 2017, чтобы понять, как работает механизм привязки аргументов.

Когда функция определена, в действии есть один или два Environment Records. Связи, установленные в записи среды, отличаются в зависимости от того, имеют ли аргументы значение по умолчанию или нет. Если аргумент имеет значения по умолчанию, тогда действуют 2 записи среды. Один для экземпляров параметров и один для объявления тела (например, переменные, внутренние функции и т.д.).

Очевидно, когда вам нравится:

function(x = 2, y = x){
  ...
}

на работе есть функция предзадания, и она должна иметь собственный контекст. Поэтому в случае <

function foo(x = 2, f = () => x) {
  var x = 5;
  console.log(f())
}

x попадает под закрытие во время определения параметров функции.

Итак, давайте прочитаем соответствующую часть спецификаций ECMA 2017, где говорится:

9.2.12 ФункцияDeclarationInstantiation (func, argumentsList)

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

Также нам дается подробный алгоритм, как реализовать эту функциональность, если нам когда-либо понадобится сесть и закодировать наш собственный движок JS. Шаг 27.a интересен.

27 Else,

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

Ответ 3

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