ECMAScript 6’s name Property

Identifying functions can be challenging in JavaScript given the various ways a function can be defined. Additionally, the prevalence of anonymous function expressions makes debugging a bit more difficult, often resulting in stack traces that are hard to read and decipher. For these reasons, ECMAScript 6 adds the name property to all functions.

Choosing Appropriate Names

All functions in an ECMAScript 6 program will have an appropriate value for their name property. To see this in action, look at the following example, which shows a function and function expression, and prints the name properties for both:

  1. function doSomething() {
  2. // ...
  3. }
  4. var doAnotherThing = function() {
  5. // ...
  6. };
  7. console.log(doSomething.name); // "doSomething"
  8. console.log(doAnotherThing.name); // "doAnotherThing"

In this code, doSomething() has a name property equal to "doSomething" because it’s a function declaration. The anonymous function expression doAnotherThing() has a name of "doAnotherThing" because that’s the name of the variable to which it is assigned.

Special Cases of the name Property

While appropriate names for function declarations and function expressions are easy to find, ECMAScript 6 goes further to ensure that all functions have appropriate names. To illustrate this, consider the following program:

  1. var doSomething = function doSomethingElse() {
  2. // ...
  3. };
  4. var person = {
  5. get firstName() {
  6. return "Nicholas"
  7. },
  8. sayName: function() {
  9. console.log(this.name);
  10. }
  11. }
  12. console.log(doSomething.name); // "doSomethingElse"
  13. console.log(person.sayName.name); // "sayName"
  14. var descriptor = Object.getOwnPropertyDescriptor(person, "firstName");
  15. console.log(descriptor.get.name); // "get firstName"

In this example, doSomething.name is "doSomethingElse" because the function expression itself has a name, and that name takes priority over the variable to which the function was assigned. The name property of person.sayName() is "sayName", as the value was interpreted from the object literal. Similarly, person.firstName is actually a getter function, so its name is "get firstName" to indicate this difference. Setter functions are prefixed with "set" as well. (Both getter and setter functions must be retrieved using Object.getOwnPropertyDescriptor().)

There are a couple of other special cases for function names, too. Functions created using bind() will have their names prefixed with "bound" and functions created using the Function constructor have a name of "anonymous", as in this example:

  1. var doSomething = function() {
  2. // ...
  3. };
  4. console.log(doSomething.bind().name); // "bound doSomething"
  5. console.log((new Function()).name); // "anonymous"

The name of a bound function will always be the name of the function being bound prefixed with the string "bound ", so the bound version of doSomething() is "bound doSomething".

Keep in mind that the value of name for any function does not necessarily refer to a variable of the same name. The name property is meant to be informative, to help with debugging, so there’s no way to use the value of name to get a reference to the function.