Почему нельзя переименовать имя выражения функции? - PullRequest
8 голосов
/ 04 июля 2019

Почему следующий фрагмент выдаст ошибку?

"use strict";
(function a() {
  console.log(typeof a); // function
  console.log(a = 0); // error
})();

Почему этот фрагмент не выдает ошибку?

"use strict";
(function() {
  function a() {
    console.log(a = 0); // 0
  }
  return a;
})()();

Почему немедленный возврат функции вызывает ошибку?

"use strict";
(function() {
  return function a() {
    console.log(a = 0); // error
  };
})()();

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

1 Ответ

5 голосов
/ 04 июля 2019

Потому что именно так ведут себя именованные FunctionExpressions, которые отличаются от того, как FunctionDeclarations do

Правила для создания именованного FunctionExpression : :

ВыражениеФункция: functionBindingIdentifier (ФормальныеПараметры) {ТелоФункция}

  1. Пусть scope будет LexicalEnvironment текущего контекста выполнения.
  2. Пусть funcEnv будет NewDeclarativeEnvironment (scope).
  3. Пусть envRec будет функцией EnvironmentRecord funcEnv.
  4. Пусть name будет StringValue BindingIdentifier.
  5. Выполнить envRec.CreateImmutableBinding (имя, ложь).
  6. Пусть closure будет FunctionCreate (Normal, FormalParameters, FunctionBody, funcEnv).
  7. Выполнить MakeConstructor (замыкание).
  8. Выполнить SetFunctionName (замыкание, имя).
  9. Установить закрытие. [[SourceText]] для исходного текста, соответствующего FunctionExpression.
  10. Выполнить envRec.InitializeBinding (имя, закрытие).
  11. Возвратное закрытие.

Важным моментом является .5 , который делает имя функции неизменяемой привязкой .


  • В первом случае вы пытаетесь переназначить эту неизменяемую привязку . бросает

  • Во втором случае, однако, ваша именованная функция не является FunctionExpression , а FunctionDeclaration , который имеет другое поведение .

  • В последнем случае это FunctionExpression , и в этом отношении он делает то же самое, что и первый.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...