Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't the name of a function expression be reassigned?

Why will the following snippet throw an error?

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

Why doesn't this snippet throw an error?

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

Why does immediately returning the function throw an error?

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

Are function expressions the only case where this happens? Why can't they be reassigned?

like image 309
nick zoum Avatar asked Jul 04 '19 08:07

nick zoum


1 Answers

Because that's how named FunctionExpressions behave, which is different than how FunctionDeclarations do

The rules to create a named FunctionExpression are:

FunctionExpression:functionBindingIdentifier(FormalParameters){FunctionBody}

  1. Let scope be the running execution context's LexicalEnvironment.
  2. Let funcEnv be NewDeclarativeEnvironment(scope).
  3. Let envRec be funcEnv's EnvironmentRecord.
  4. Let name be StringValue of BindingIdentifier.
  5. Perform envRec.CreateImmutableBinding(name, false).
  6. Let closure be FunctionCreate(Normal, FormalParameters, FunctionBody, funcEnv).
  7. Perform MakeConstructor(closure).
  8. Perform SetFunctionName(closure, name).
  9. Set closure.[[SourceText]] to the source text matched by FunctionExpression.
  10. Perform envRec.InitializeBinding(name, closure).
  11. Return closure.

The important point is the .5 which does make the name of the function an immutable binding.


  • In the first case, you try to reassign this Immutable Binding. It throws

  • In the second case however, your named function is not a FunctionExpression, but a FunctionDeclaration, which has different behavior.

  • In the last case, it's a FunctionExpression and to this regards does the same as the first one.

like image 150
Kaiido Avatar answered Oct 04 '22 19:10

Kaiido