Подняты ли параметры функции в JavaScript? - PullRequest
4 голосов
/ 09 мая 2020

function foo(a,b){
  return a + b;
}

foo(1,2);

Поднимаются ли параметры функции?

Имеет ли значение variableEnvirnoment на этапе создания контекста выполнения функции примерно следующее:

VE = {
        { 0 : undefined , 1: undefined, length: 2 },
        {a : undefined, b: undefined},
        outer: refToGlobalLE
     }

Ответы [ 2 ]

3 голосов
/ 09 мая 2020

Да, параметры подняты.

Когда функция вызывается, каждое объявление в теле функции (var, let, const и объявления функций) создается в записи среды для этого выполнения контекст. Каждый формальный параметр также добавляется в запись среды таким же образом ([9.2.10 21. c .i и 9.2.10 28.ei2]). Полный процесс описан в разделе 9.2.10 spe c.

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

Это означает, что формальные привязки параметров добавляются в то же логическое место таким же образом, что и объявления тела функции ie. var, let, const и объявления функций ( все из которых, кстати, подняты ). И это означает, что привязки формальных параметров инициализируются так же, как объявления функций (ie. Их соответствующее значение устанавливается в верхней части функции).

Подъем - это функция времени и места создания привязки идентификатора. Формальные привязки параметров создаются (и инициализируются) так же, как объявления функций. Мы знаем, что объявления функций поднимаются, поэтому привязки параметров поднимаются. QED.

До ES2015 этот подъем был, насколько я знаю, невидимым, потому что параметры функции уже находятся на самом верху функции. Однако в ES2015 был добавлен синтаксис инициализатора значения параметра по умолчанию, что сделало подъем видимым в пользовательском пространстве.

Если формальные параметры не были подняты, следующий код не будет выдавать "Uncaught ReferenceError: Cannot access 'x' before initialization", потому что по умолчанию значение параметра для z будет относиться к внешнему x:

var x = 'global'
(function(y, z = x, x) {}()) // "Uncaught ReferenceError: Cannot access 'x' before initialization"

В вашем комментарии говорится, что ' при условии, что параметры подняты, x будет [инициализирован как] «undefined», и в результате ошибка не будет происходит, поскольку x уже инициализировано '. Вы подразумеваете, что подъем может также использоваться для объяснения отсутствия ошибки. Это верно, , но из этого не следует, что, если наблюдается ошибка, подъем не может происходить . Действительно, мы можем видеть, что подъем происходит, потому что, как указано в сообщении об ошибке, x в z = x используется для ссылки на формальный параметр x, который объявлен позже в тексте программы. Это возможно только в случае подъема.

2 голосов
/ 09 мая 2020

Нет, параметры функций не поднимаются в JavaScript.

function foo(a,b){
  return a + b;
}

foo(1,2);

Чтобы вкратце объяснить вам весь процесс, я хотел бы объяснить, как вызывается сама функция. Итак, поскольку вы говорите о переменной среде (которая в данном случае будет глобальным контекстом выполнения), поток выполнения JavaScript, который в основном выполняет код построчно, сохранит код определения функции как значение переменной foo в памяти и еще не выполняет (просто сохраняет определение как есть). Он переходит к следующей строке выполнения, которая, по-видимому, вызывает вызов функции (используя круглые скобки) для определения функции foo.

Теперь, когда эта функция вызывается foo (1,2), сначала создается новый контекст выполнения внутри глобального выполнения для этой функции foo. Вы можете представить это как абстрактную коробку внутри. Аргументы 1 и 2 сопоставляются с параметрами 'a' и 'b' функции как переменные внутри контекста выполнения foo, а не глобального контекста выполнения. Затем функция просто возвращает значение a + b в глобальный контекст выполнения через стек вызовов.

Хорошо, чтобы проверить это, если бы вы просто вызвали функцию, а затем после этого определили ее как ниже

foo(1,2);

function foo(a,b){
  return a + b;
}

Вероятно, вы получите сообщение об ошибке, поскольку определение функции foo отсутствует в глобальном контексте выполнения и в основном приведет к ОШИБКЕ ССЫЛКИ.

Теперь поговорим о параметрах независимо от того, поднимаются они или нет. Тогда нет! Они сами создаются при вызове функции и создании нового контекста выполнения. Эти переменные привязаны к блоку для функции и не видны внешнему / глобальному контексту выполнения. Поэтому, когда функция возвращается вызываемому, переменная внутри нее просто собирается мусором.

Надеюсь, что это ответит на ваш вопрос.

...