2

Consider the following code.

const foo = () => {};
console.log(foo.name); // prints foo
const bar = foo;
console.log(bar.name); // prints foo again

Please point out what is wrong with my reasoning about the statement const foo = () => {};. The expression () => {} evaluates to an anonymous function object and the statement binds the name foo to that object. Surely the value of the expression () => {} does not know it has name foo, but somehow it knows after foo is bound to it. But how did that happen? I assume that = does not alter the right-hand side and lines 3 and 4 behave as I expected.

lamc
  • 347
  • 2
  • 5
  • 2
    Because those aren't anonymous functions, they're function expressions. Here's some further reading on the differences: https://stackoverflow.com/q/336859/519413 – Rory McCrossan Sep 21 '22 at 16:28
  • 2
    Yes, it infers its name from its syntactic position. So `const foo = () => {}` sets the `.name` property on the Function you just created. When you reassign the reference, `.name` has already been set which is why `const bar = foo` has `bar.name === 'foo'`. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#variable_declaration_and_method – romellem Sep 21 '22 at 16:31

2 Answers2

3

According to the specification, when a variable declaration is evaluated and the initializer is an anonymous function definition, then that definition is evaluated in a special way, passing along the name of the variable to be used as function name:

LexicalBinding : BindingIdentifier Initializer
1. Let bindingId be StringValue of BindingIdentifier.
2. Let lhs be ! ResolveBinding(bindingId).
3. If IsAnonymousFunctionDefinition(Initializer) is true, then
   a. Let value be ? NamedEvaluation of Initializer with argument bindingId.
...

Something similar happens when evaluating an assignment expression.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
1

Line 1 of your code technically isn't an anonymous function, it's a "implicitly named" function expression (or as the mdn also calls it, an "unnamed function").

From the mdn:

The variable to which the function expression is assigned will have a name property. The name doesn't change if it's assigned to a different variable. If function name is omitted, it will be the variable name (implicit name). If function name is present, it will be the function name (explicit name). This also applies to arrow functions (arrows don't have a name so you can only give the variable an implicit name).

See also: Function.name#function_expression

Sean Sutherland
  • 377
  • 2
  • 14