3

Since ECMAScript 6, most function objects have a name property defined.

Now, if an anonymous function expression is assigned to a variable or is part of a property definition inside an object initializer, the identifier of the variable or the name of the property will be the value of the name property of the function object.

const a = function () {};
console.log(a.name); // a

const object = {
  b : function () {}
};
console.log(object.b.name); // b

I don't have problems to understand the spec regarding the documented semantic of this behaviour, but I can't really see, why an assignment to a left hand side member expression as in the following example does not affect the name property of the function, which seems to be the case.

const object = {};
object.c = function () {};
console.log(object.c.name); //

As part of the member expression, there is obviously an indentifier which could (and should?) be used as the value of the name property. Even if the property name would be an expression inside brackets, this should be no problem, since using computed property names inside an object initializer does not prevent the name property of the anonymous function to be defined either.

It would be great, if someone could confirm that the observed behaviour is conforming to the spec and anyway, explain in short the specific semantics that apply to this syntax.

SickBoy
  • 225
  • 2
  • 9
  • 1
    Yes, this is a weird part of the spec, you've read it correctly. https://esdiscuss.org/topic/name-anonymous-functions-on-property-assignments – Bergi Apr 08 '16 at 11:36
  • 1
    Hello Bergi. Thanks for the link (*and the link in the link*). Now I see that I didn't misunderstand `IsIdentifierRef`. I just wasn't sure about that and seeked for some confirmation, because the behaviour resulting from this seemed completely inconsistend to me, as you've mentioned during this discussion, too. Sadly, ES 2017 also doens't seem to change anything about [this](https://tc39.github.io/ecma262/#sec-static-semantics-static-semantics-isidentifierref). :-( – SickBoy Apr 08 '16 at 12:00

1 Answers1

3

This first snippet is described under assignment operators:

e. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then

i. Let hasNameProperty be HasOwnProperty(rval, "name").

ii. ReturnIfAbrupt(hasNameProperty).

iii. If hasNameProperty is false, perform SetFunctionName(rval, GetReferencedName(lref)).

When you assign to a MemberExpression, as in your last snippet, IsIdentifierRef(LeftHandSideExpression) is false and no conversion takes place.

If you search the standard for IsAnonymousFunctionDefinition you'll find a couple of other cases where this logic is used (object initializers, destructuring assignments).

IsIdentifierRef is defined twice (here and here), and both definitions boil down to "if an expression is IdentifierReference return true otherwise return false", where IdentifierReference is an Identifier (the yield stuff is for backward compatibility with non-strict code).

Community
  • 1
  • 1
georg
  • 211,518
  • 52
  • 313
  • 390
  • Hello georg and thank you for your answer. I already found the algorithm steps you posted and it seems obvious that `IsAnonymousFunctionDefinition(AssignmentExpression)` should return true in this case, but I have trouble to understand, why exactly `IsIdentifierRef` returns false, even though an identifier could be retrieved. – SickBoy Apr 08 '16 at 11:20
  • I think, I finally got it. :-) It was just that it seemed not to be resulting in consistend behaviour, and therefore I was not sure, that I didn't possibly overlook some *hidden rule* that would apply in this case. So thanks again to you and Bergi to make things clear! – SickBoy Apr 08 '16 at 12:16