ℹ️ Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 0.1 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://2ality.com/2015/09/function-names-es6.html |
| Last Crawled | 2026-04-06 09:50:02 (1 day ago) |
| First Indexed | 2019-07-01 14:37:22 (6 years ago) |
| HTTP Status Code | 200 |
| Meta Title | The names of functions in ES6 |
| Meta Description | Update 2015-12-26: Sections for two caveats: “the name of a function is always assigned at creation” and “minification” The name property of a function contains its name: > function foo() {} > foo.name 'foo' This property is useful for debugging (its value shows up in stack traces) and some metaprogramming tasks (picking a function by name etc.). Prior to ECMAScript 6 (ES6), this property was already supported by most engines. With ES6, it becomes part of the language standard and is frequently filled in automatically. |
| Meta Canonical | null |
| Boilerpipe Text | Update 2015-12-26:
Sections for two caveats: “
the name of a function is always assigned at creation
” and “
minification
”
The
name
property of a function contains its name:
>
function
foo
(
) {}
>
foo.
name
'foo'
This property is useful for debugging (its value shows up in stack traces) and some metaprogramming tasks (picking a function by name etc.).
Prior to ECMAScript 6 (ES6), this property was already supported by most engines. With ES6, it becomes part of the language standard and is frequently filled in automatically.
Constructs that provide names for functions Â
The following sections describe how
name
is set up automatically for various programming constructs.
Variable declarations and assignments Â
Functions pick up names if they are created via variable declarations:
let
func1 =
function
(
) {};
console
.
log
(func1.
name
);
// func1
const
func2 =
function
(
) {};
console
.
log
(func2.
name
);
// func2
var
func3 =
function
(
) {};
console
.
log
(func3.
name
);
// func3
But even with a normal assignment,
name
is set up properly:
let
func4;
func4 =
function
(
) {};
console
.
log
(func4.
name
);
// func4
var
func5;
func5 =
function
(
) {};
console
.
log
(func5.
name
);
// func5
With regard to names, arrow functions are like anonymous function expressions:
const
func
= (
) => {};
console
.
log
(func.
name
);
// func
From now on, whenever you see an anonymous function expression, you can assume that an arrow function works the same way.
Default values Â
If a function is a default value, it gets its name from its variable or parameter:
let
[func1 =
function
(
) {}] = [];
console
.
log
(func1.
name
);
// func1
let
{
f2
: func2 =
function
(
) {} } = {};
console
.
log
(func2.
name
);
// func2
function
g
(
func3 =
function
() {}
) {
return
func3.
name
;
}
console
.
log
(
g
());
// func3
Named function definitions Â
Function declarations and function expression are
function definitions
. This scenario has been supported for a long time: a function definition with a name passes it on to the
name
property.
For example, a function declaration:
function
foo
(
) {}
console
.
log
(foo.
name
);
// foo
The name of a named function expression also sets up the
name
property.
const
bar =
function
baz
(
) {};
console
.
log
(bar.
name
);
// baz
Because it comes first, the function expression’s name
baz
takes precedence over other names (e.g. the name
bar
provided via the variable declaration):
However, as in ES5, the name of a function expression is only a variable inside the function expression:
const
bar =
function
baz
(
) {
console
.
log
(baz.
name
);
// baz
};
bar
();
console
.
log
(baz);
// ReferenceError
Methods in object literals Â
If a function is the value of a property, it gets its name from that property. It doesn’t matter if that happens via a method definition (line A), a traditional property definition (line B), a property definition with a computed property key (line C) or a property value shorthand (line D).
function
func
(
) {}
let
obj = {
m1
(
) {},
// (A)
m2
:
function
(
) {},
// (B)
[
'm'
+
'3'
]:
function
(
) {},
// (C)
func,
// (D)
};
console
.
log
(obj.
m1
.
name
);
// m1
console
.
log
(obj.
m2
.
name
);
// m2
console
.
log
(obj.
m3
.
name
);
// m3
console
.
log
(obj.
func
.
name
);
// func
The names of getters are prefixed with
'get'
, the names of setters are prefixed with
'set'
:
let
obj = {
get
foo
() {},
set
bar
(
value
) {},
};
let
getter =
Object
.
getOwnPropertyDescriptor
(obj,
'foo'
).
get
;
console
.
log
(getter.
name
);
// 'get foo'
let
setter =
Object
.
getOwnPropertyDescriptor
(obj,
'bar'
).
set
;
console
.
log
(setter.
name
);
// 'set bar'
Methods in class definitions Â
The naming of methods in class definitions is similar to object literals:
class
C
{
m1
(
) {}
[
'm'
+
'2'
]() {}
// computed property key
static
classMethod
(
) {}
}
console
.
log
(C.
prototype
.
m1
.
name
);
// m1
console
.
log
(
new
C
().
m1
.
name
);
// m1
console
.
log
(C.
prototype
.
m2
.
name
);
// m2
console
.
log
(C.
classMethod
.
name
);
// classMethod
Getters and setters again have the name prefixes
'get'
and
'set'
, respectively:
class
C
{
get
foo
() {}
set
bar
(
value
) {}
}
let
getter =
Object
.
getOwnPropertyDescriptor
(C.
prototype
,
'foo'
).
get
;
console
.
log
(getter.
name
);
// 'get foo'
let
setter =
Object
.
getOwnPropertyDescriptor
(C.
prototype
,
'bar'
).
set
;
console
.
log
(setter.
name
);
// 'set bar'
Methods whose keys are symbols Â
In ES6, the key of a method can be a symbol. The
name
property of such a method is still a string:
If the symbol has a description, the method’s name is the description in square brackets.
Otherwise, the method’s name is the empty string (
''
).
const
key1 =
Symbol
(
'description'
);
const
key2 =
Symbol
();
let
obj = {
[key1]() {},
[key2]() {},
};
console
.
log
(obj[key1].
name
);
// '[description]'
console
.
log
(obj[key2].
name
);
// ''
Class definitions Â
Remember that class definitions create functions. Those functions also have their property
name
set up correctly:
class
Foo
{}
console
.
log
(
Foo
.
name
);
// Foo
const
Bar
=
class
{};
console
.
log
(
Bar
.
name
);
// Bar
Default exports Â
All of the following statements set
name
to
'default'
:
export
default
function
(
) {}
export
default
(
function
(
) {});
export
default
class
{}
export
default
(
class
{});
export
default
() => {};
Other programming constructs Â
Generator functions and generator methods get their names the same way that normal functions and methods do.
new Function()
produces functions whose
name
is
'anonymous'
.
A webkit bug
describes why that is necessary on the web.
func.bind(···)
produces a function whose
name
is
'bound '+func.name
:
function
foo
(
x
) {
return
x
}
const
bound = foo.
bind
(
undefined
,
123
);
console
.
log
(bound.
name
);
// 'bound foo'
Caveats Â
Caveat: the name of a function is always assigned at creation Â
Function names are always assigned during creation and never changed later on. That is, JavaScript engines detect the previously mentioned patterns and create functions that start their lives with the correct names. The following code demonstrates that the name of the function created by
functionFactory()
is assigned in line A and not changed by the declaration in line B.
function
functionFactory
(
) {
return
function
(
) {};
// (A)
}
const
foo =
functionFactory
();
// (B)
console
.
log
(foo.
name
.
length
);
// 0 (anonymous)
One could, in theory, check for each assignment whether the right-hand side evaluates to a function and whether that function doesn’t have a name, yet. But that would incur a significant performance penalty.
Caveat: minification Â
Function names are subject to minification, which means that they will usually change in minified code. Depending on what you want to do, you may have to manage function names via strings (which are not minified) or you may have to tell your minifier what names not to minify.
Changing the names of functions Â
These are the attributes of property
name
:
>
let
func =
function
(
) {}
>
Object
.
getOwnPropertyDescriptor
(func,
'name'
)
{ value: 'func',
writable: false,
enumerable: false,
configurable: true }
The property not being writable means that you can’t change its value via assignment:
>
func.
name
=
'foo'
;
>
func.
name
'func'
The property is, however, configurable, which means that you can change it by re-defining it:
>
Object
.
defineProperty
(func,
'name'
, {
value
:
'foo'
,
configurable
:
true
});
>
func.
name
'foo'
If the property
name
already exists then you can omit the descriptor property
configurable
, because missing descriptor properties mean that the corresponding attributes are not changed.
If the property
name
does not exist yet then the descriptor property
configurable
ensures that
name
remains configurable (the default attribute values are all
false
or
undefined
).
The function property
name
in the spec Â
The spec operation
SetFunctionName()
sets up the property
name
. Search for its name in the spec to find out where that happens.
The third parameter of that operations specifies a name prefix. It is used for:
Getters and setters
(prefixes
'get'
and
'set'
)
Function.prototype.bind()
(prefix
'bound'
)
Anonymous function expressions not having a property
name
can be seen by looking at
their runtime semantics
:
The names of named function expressions are set up via
SetFunctionName()
. That operation is not invoked for anonymous function expressions.
The names of function declarations are set up when entering a scope (they are hoisted!).
When an arrow function is created
, no name is set up, either (
SetFunctionName()
is not invoked).
Suport for the
name
property in engines Â
In Kangax’ ES6 table
, you can see that no engine currently fully supports
name
, not even Babel. Thus, the code in this blog post shows how things
should be
, not how they are in any single engine.
Further reading:
“
Callable entities in ECMAScript 6
” in “Exploring ES6”. |
| Markdown | [2ality – JavaScript and more](https://2ality.com/index.html)
[Home](https://2ality.com/index.html)\|[About](https://2ality.com/p/about.html)\|[Follow](https://2ality.com/p/follow.html)\|[Archive](https://2ality.com/archive.html)\|
[Search](https://www.ecosia.org/search?q=site%3Ahttps%3A%2F%2F2ality.com%2F)

\|
[Books](https://exploringjs.com/)

# The names of functions in ES6
\[2015-09-10\] [esnext](https://2ality.com/archive.html#Tag=esnext), [dev](https://2ality.com/archive.html#Tag=dev), [javascript](https://2ality.com/archive.html#Tag=javascript)
(Ad, please don’t block)
**Update 2015-12-26:** Sections for two caveats: “[the name of a function is always assigned at creation](https://2ality.com/2015/09/function-names-es6.html#caveat-names-assigned-at-creation)” and “[minification](https://2ality.com/2015/09/function-names-es6.html#caveat-minification)”
The `name` property of a function contains its name:
```
> function foo() {}
> foo.name
'foo'
```
This property is useful for debugging (its value shows up in stack traces) and some metaprogramming tasks (picking a function by name etc.).
Prior to ECMAScript 6 (ES6), this property was already supported by most engines. With ES6, it becomes part of the language standard and is frequently filled in automatically.
## Constructs that provide names for functions [\#](https://2ality.com/2015/09/function-names-es6.html#constructs-that-provide-names-for-functions)
The following sections describe how `name` is set up automatically for various programming constructs.
### Variable declarations and assignments [\#](https://2ality.com/2015/09/function-names-es6.html#variable-declarations-and-assignments)
Functions pick up names if they are created via variable declarations:
```
let func1 = function () {};
console.log(func1.name); // func1
const func2 = function () {};
console.log(func2.name); // func2
var func3 = function () {};
console.log(func3.name); // func3
```
But even with a normal assignment, `name` is set up properly:
```
let func4;
func4 = function () {};
console.log(func4.name); // func4
var func5;
func5 = function () {};
console.log(func5.name); // func5
```
With regard to names, arrow functions are like anonymous function expressions:
```
const func = () => {};
console.log(func.name); // func
```
From now on, whenever you see an anonymous function expression, you can assume that an arrow function works the same way.
### Default values [\#](https://2ality.com/2015/09/function-names-es6.html#default-values)
If a function is a default value, it gets its name from its variable or parameter:
```
let [func1 = function () {}] = [];
console.log(func1.name); // func1
let { f2: func2 = function () {} } = {};
console.log(func2.name); // func2
function g(func3 = function () {}) {
return func3.name;
}
console.log(g()); // func3
```
### Named function definitions [\#](https://2ality.com/2015/09/function-names-es6.html#named-function-definitions)
Function declarations and function expression are *function definitions*. This scenario has been supported for a long time: a function definition with a name passes it on to the `name` property.
For example, a function declaration:
```
function foo() {}
console.log(foo.name); // foo
```
The name of a named function expression also sets up the `name` property.
```
const bar = function baz() {};
console.log(bar.name); // baz
```
Because it comes first, the function expression’s name `baz` takes precedence over other names (e.g. the name `bar` provided via the variable declaration):
However, as in ES5, the name of a function expression is only a variable inside the function expression:
```
const bar = function baz() {
console.log(baz.name); // baz
};
bar();
console.log(baz); // ReferenceError
```
### Methods in object literals [\#](https://2ality.com/2015/09/function-names-es6.html#methods-in-object-literals)
If a function is the value of a property, it gets its name from that property. It doesn’t matter if that happens via a method definition (line A), a traditional property definition (line B), a property definition with a computed property key (line C) or a property value shorthand (line D).
```
function func() {}
let obj = {
m1() {}, // (A)
m2: function () {}, // (B)
['m' + '3']: function () {}, // (C)
func, // (D)
};
console.log(obj.m1.name); // m1
console.log(obj.m2.name); // m2
console.log(obj.m3.name); // m3
console.log(obj.func.name); // func
```
The names of getters are prefixed with `'get'`, the names of setters are prefixed with `'set'`:
```
let obj = {
get foo() {},
set bar(value) {},
};
let getter = Object.getOwnPropertyDescriptor(obj, 'foo').get;
console.log(getter.name); // 'get foo'
let setter = Object.getOwnPropertyDescriptor(obj, 'bar').set;
console.log(setter.name); // 'set bar'
```
### Methods in class definitions [\#](https://2ality.com/2015/09/function-names-es6.html#methods-in-class-definitions)
The naming of methods in class definitions is similar to object literals:
```
class C {
m1() {}
['m' + '2']() {} // computed property key
static classMethod() {}
}
console.log(C.prototype.m1.name); // m1
console.log(new C().m1.name); // m1
console.log(C.prototype.m2.name); // m2
console.log(C.classMethod.name); // classMethod
```
Getters and setters again have the name prefixes `'get'` and `'set'`, respectively:
```
class C {
get foo() {}
set bar(value) {}
}
let getter = Object.getOwnPropertyDescriptor(C.prototype, 'foo').get;
console.log(getter.name); // 'get foo'
let setter = Object.getOwnPropertyDescriptor(C.prototype, 'bar').set;
console.log(setter.name); // 'set bar'
```
### Methods whose keys are symbols [\#](https://2ality.com/2015/09/function-names-es6.html#methods-whose-keys-are-symbols)
In ES6, the key of a method can be a symbol. The `name` property of such a method is still a string:
- If the symbol has a description, the method’s name is the description in square brackets.
- Otherwise, the method’s name is the empty string (`''`).
```
const key1 = Symbol('description');
const key2 = Symbol();
let obj = {
[key1]() {},
[key2]() {},
};
console.log(obj[key1].name); // '[description]'
console.log(obj[key2].name); // ''
```
### Class definitions [\#](https://2ality.com/2015/09/function-names-es6.html#class-definitions)
Remember that class definitions create functions. Those functions also have their property `name` set up correctly:
```
class Foo {}
console.log(Foo.name); // Foo
const Bar = class {};
console.log(Bar.name); // Bar
```
### Default exports [\#](https://2ality.com/2015/09/function-names-es6.html#default-exports)
All of the following statements set `name` to `'default'`:
```
export default function () {}
export default (function () {});
export default class {}
export default (class {});
export default () => {};
```
### Other programming constructs [\#](https://2ality.com/2015/09/function-names-es6.html#other-programming-constructs)
- Generator functions and generator methods get their names the same way that normal functions and methods do.
- `new Function()` produces functions whose `name` is `'anonymous'`. [A webkit bug](https://bugs.webkit.org/show_bug.cgi?id=7726) describes why that is necessary on the web.
- `func.bind(···)` produces a function whose `name` is `'bound '+func.name`:
```
function foo(x) {
return x
}
const bound = foo.bind(undefined, 123);
console.log(bound.name); // 'bound foo'
```
## Caveats [\#](https://2ality.com/2015/09/function-names-es6.html#caveats)
### Caveat: the name of a function is always assigned at creation [\#](https://2ality.com/2015/09/function-names-es6.html#caveat-names-assigned-at-creation)
Function names are always assigned during creation and never changed later on. That is, JavaScript engines detect the previously mentioned patterns and create functions that start their lives with the correct names. The following code demonstrates that the name of the function created by `functionFactory()` is assigned in line A and not changed by the declaration in line B.
```
function functionFactory() {
return function () {}; // (A)
}
const foo = functionFactory(); // (B)
console.log(foo.name.length); // 0 (anonymous)
```
One could, in theory, check for each assignment whether the right-hand side evaluates to a function and whether that function doesn’t have a name, yet. But that would incur a significant performance penalty.
### Caveat: minification [\#](https://2ality.com/2015/09/function-names-es6.html#caveat-minification)
Function names are subject to minification, which means that they will usually change in minified code. Depending on what you want to do, you may have to manage function names via strings (which are not minified) or you may have to tell your minifier what names not to minify.
## Changing the names of functions [\#](https://2ality.com/2015/09/function-names-es6.html#changing-the-names-of-functions)
These are the attributes of property `name`:
```
> let func = function () {}
> Object.getOwnPropertyDescriptor(func, 'name')
{ value: 'func',
writable: false,
enumerable: false,
configurable: true }
```
The property not being writable means that you can’t change its value via assignment:
```
> func.name = 'foo';
> func.name
'func'
```
The property is, however, configurable, which means that you can change it by re-defining it:
```
> Object.defineProperty(func, 'name', {value: 'foo', configurable: true});
> func.name
'foo'
```
If the property `name` already exists then you can omit the descriptor property `configurable`, because missing descriptor properties mean that the corresponding attributes are not changed.
If the property `name` does not exist yet then the descriptor property `configurable` ensures that `name` remains configurable (the default attribute values are all `false` or `undefined`).
## The function property `name` in the spec [\#](https://2ality.com/2015/09/function-names-es6.html#the-function-property-name-in-the-spec)
- The spec operation [`SetFunctionName()`](http://www.ecma-international.org/ecma-262/6.0/#sec-setfunctionname) sets up the property `name`. Search for its name in the spec to find out where that happens.
- The third parameter of that operations specifies a name prefix. It is used for:
- [Getters and setters](http://www.ecma-international.org/ecma-262/6.0/#sec-method-definitions-runtime-semantics-propertydefinitionevaluation) (prefixes `'get'` and `'set'`)
- [`Function.prototype.bind()`](http://www.ecma-international.org/ecma-262/6.0/#sec-function.prototype.bind) (prefix `'bound'`)
- Anonymous function expressions not having a property `name` can be seen by looking at [their runtime semantics](http://www.ecma-international.org/ecma-262/6.0/#sec-function-definitions-runtime-semantics-evaluation):
- The names of named function expressions are set up via `SetFunctionName()`. That operation is not invoked for anonymous function expressions.
- The names of function declarations are set up when entering a scope (they are hoisted!).
- [When an arrow function is created](http://www.ecma-international.org/ecma-262/6.0/#sec-arrow-function-definitions-runtime-semantics-evaluation), no name is set up, either (`SetFunctionName()` is not invoked).
## Suport for the `name` property in engines [\#](https://2ality.com/2015/09/function-names-es6.html#suport-for-the-name-property-in-engines)
[In Kangax’ ES6 table](https://kangax.github.io/compat-table/es6/#function_name_property), you can see that no engine currently fully supports `name`, not even Babel. Thus, the code in this blog post shows how things *should be*, not how they are in any single engine.
**Further reading:** “[Callable entities in ECMAScript 6](http://exploringjs.com/es6/ch_callables.html)” in “Exploring ES6”.
Please enable JavaScript to view the [comments powered by Disqus.](https://disqus.com/?ref_noscript)
[](https://dr-axel.de/)
**Dr. Axel Rauschmayer**
[Homepage](https://dr-axel.de/) \| [Mastodon](https://fosstodon.org/@rauschma)
[](https://exploringjs.com/js/)
[Exploring JavaScript](https://exploringjs.com/js/)
Book (free online) and exercises
[](https://exploringjs.com/deep-js/)
[Deep JavaScript](https://exploringjs.com/deep-js/)
Book (free online)
[](https://exploringjs.com/ts/)
[Exploring TypeScript](https://exploringjs.com/ts/)
Book (free online)
[](https://exploringjs.com/nodejs-shell-scripting/)
[Node.js shell scripting](https://exploringjs.com/nodejs-shell-scripting/)
Book (free online)
[](https://ecmascript.news/?utm_source=2ality&utm_medium=banner&utm_campaign=sidebar)
[ECMAScript News](https://ecmascript.news/?utm_source=2ality&utm_medium=banner&utm_campaign=sidebar)
Newsletter (free) |
| Readable Markdown | **Update 2015-12-26:** Sections for two caveats: “[the name of a function is always assigned at creation](https://2ality.com/2015/09/function-names-es6.html#caveat-names-assigned-at-creation)” and “[minification](https://2ality.com/2015/09/function-names-es6.html#caveat-minification)”
The `name` property of a function contains its name:
```
> function foo() {}
> foo.name
'foo'
```
This property is useful for debugging (its value shows up in stack traces) and some metaprogramming tasks (picking a function by name etc.).
Prior to ECMAScript 6 (ES6), this property was already supported by most engines. With ES6, it becomes part of the language standard and is frequently filled in automatically.
## Constructs that provide names for functions
The following sections describe how `name` is set up automatically for various programming constructs.
### Variable declarations and assignments
Functions pick up names if they are created via variable declarations:
```
let func1 = function () {};
console.log(func1.name); // func1
const func2 = function () {};
console.log(func2.name); // func2
var func3 = function () {};
console.log(func3.name); // func3
```
But even with a normal assignment, `name` is set up properly:
```
let func4;
func4 = function () {};
console.log(func4.name); // func4
var func5;
func5 = function () {};
console.log(func5.name); // func5
```
With regard to names, arrow functions are like anonymous function expressions:
```
const func = () => {};
console.log(func.name); // func
```
From now on, whenever you see an anonymous function expression, you can assume that an arrow function works the same way.
### Default values
If a function is a default value, it gets its name from its variable or parameter:
```
let [func1 = function () {}] = [];
console.log(func1.name); // func1
let { f2: func2 = function () {} } = {};
console.log(func2.name); // func2
function g(func3 = function () {}) {
return func3.name;
}
console.log(g()); // func3
```
### Named function definitions
Function declarations and function expression are *function definitions*. This scenario has been supported for a long time: a function definition with a name passes it on to the `name` property.
For example, a function declaration:
```
function foo() {}
console.log(foo.name); // foo
```
The name of a named function expression also sets up the `name` property.
```
const bar = function baz() {};
console.log(bar.name); // baz
```
Because it comes first, the function expression’s name `baz` takes precedence over other names (e.g. the name `bar` provided via the variable declaration):
However, as in ES5, the name of a function expression is only a variable inside the function expression:
```
const bar = function baz() {
console.log(baz.name); // baz
};
bar();
console.log(baz); // ReferenceError
```
### Methods in object literals
If a function is the value of a property, it gets its name from that property. It doesn’t matter if that happens via a method definition (line A), a traditional property definition (line B), a property definition with a computed property key (line C) or a property value shorthand (line D).
```
function func() {}
let obj = {
m1() {}, // (A)
m2: function () {}, // (B)
['m' + '3']: function () {}, // (C)
func, // (D)
};
console.log(obj.m1.name); // m1
console.log(obj.m2.name); // m2
console.log(obj.m3.name); // m3
console.log(obj.func.name); // func
```
The names of getters are prefixed with `'get'`, the names of setters are prefixed with `'set'`:
```
let obj = {
get foo() {},
set bar(value) {},
};
let getter = Object.getOwnPropertyDescriptor(obj, 'foo').get;
console.log(getter.name); // 'get foo'
let setter = Object.getOwnPropertyDescriptor(obj, 'bar').set;
console.log(setter.name); // 'set bar'
```
### Methods in class definitions
The naming of methods in class definitions is similar to object literals:
```
class C {
m1() {}
['m' + '2']() {} // computed property key
static classMethod() {}
}
console.log(C.prototype.m1.name); // m1
console.log(new C().m1.name); // m1
console.log(C.prototype.m2.name); // m2
console.log(C.classMethod.name); // classMethod
```
Getters and setters again have the name prefixes `'get'` and `'set'`, respectively:
```
class C {
get foo() {}
set bar(value) {}
}
let getter = Object.getOwnPropertyDescriptor(C.prototype, 'foo').get;
console.log(getter.name); // 'get foo'
let setter = Object.getOwnPropertyDescriptor(C.prototype, 'bar').set;
console.log(setter.name); // 'set bar'
```
### Methods whose keys are symbols
In ES6, the key of a method can be a symbol. The `name` property of such a method is still a string:
- If the symbol has a description, the method’s name is the description in square brackets.
- Otherwise, the method’s name is the empty string (`''`).
```
const key1 = Symbol('description');
const key2 = Symbol();
let obj = {
[key1]() {},
[key2]() {},
};
console.log(obj[key1].name); // '[description]'
console.log(obj[key2].name); // ''
```
### Class definitions
Remember that class definitions create functions. Those functions also have their property `name` set up correctly:
```
class Foo {}
console.log(Foo.name); // Foo
const Bar = class {};
console.log(Bar.name); // Bar
```
### Default exports
All of the following statements set `name` to `'default'`:
```
export default function () {}
export default (function () {});
export default class {}
export default (class {});
export default () => {};
```
### Other programming constructs
- Generator functions and generator methods get their names the same way that normal functions and methods do.
- `new Function()` produces functions whose `name` is `'anonymous'`. [A webkit bug](https://bugs.webkit.org/show_bug.cgi?id=7726) describes why that is necessary on the web.
- `func.bind(···)` produces a function whose `name` is `'bound '+func.name`:
```
function foo(x) {
return x
}
const bound = foo.bind(undefined, 123);
console.log(bound.name); // 'bound foo'
```
## Caveats
### Caveat: the name of a function is always assigned at creation
Function names are always assigned during creation and never changed later on. That is, JavaScript engines detect the previously mentioned patterns and create functions that start their lives with the correct names. The following code demonstrates that the name of the function created by `functionFactory()` is assigned in line A and not changed by the declaration in line B.
```
function functionFactory() {
return function () {}; // (A)
}
const foo = functionFactory(); // (B)
console.log(foo.name.length); // 0 (anonymous)
```
One could, in theory, check for each assignment whether the right-hand side evaluates to a function and whether that function doesn’t have a name, yet. But that would incur a significant performance penalty.
### Caveat: minification
Function names are subject to minification, which means that they will usually change in minified code. Depending on what you want to do, you may have to manage function names via strings (which are not minified) or you may have to tell your minifier what names not to minify.
## Changing the names of functions
These are the attributes of property `name`:
```
> let func = function () {}
> Object.getOwnPropertyDescriptor(func, 'name')
{ value: 'func',
writable: false,
enumerable: false,
configurable: true }
```
The property not being writable means that you can’t change its value via assignment:
```
> func.name = 'foo';
> func.name
'func'
```
The property is, however, configurable, which means that you can change it by re-defining it:
```
> Object.defineProperty(func, 'name', {value: 'foo', configurable: true});
> func.name
'foo'
```
If the property `name` already exists then you can omit the descriptor property `configurable`, because missing descriptor properties mean that the corresponding attributes are not changed.
If the property `name` does not exist yet then the descriptor property `configurable` ensures that `name` remains configurable (the default attribute values are all `false` or `undefined`).
## The function property `name` in the spec
- The spec operation [`SetFunctionName()`](http://www.ecma-international.org/ecma-262/6.0/#sec-setfunctionname) sets up the property `name`. Search for its name in the spec to find out where that happens.
- The third parameter of that operations specifies a name prefix. It is used for:
- [Getters and setters](http://www.ecma-international.org/ecma-262/6.0/#sec-method-definitions-runtime-semantics-propertydefinitionevaluation) (prefixes `'get'` and `'set'`)
- [`Function.prototype.bind()`](http://www.ecma-international.org/ecma-262/6.0/#sec-function.prototype.bind) (prefix `'bound'`)
- Anonymous function expressions not having a property `name` can be seen by looking at [their runtime semantics](http://www.ecma-international.org/ecma-262/6.0/#sec-function-definitions-runtime-semantics-evaluation):
- The names of named function expressions are set up via `SetFunctionName()`. That operation is not invoked for anonymous function expressions.
- The names of function declarations are set up when entering a scope (they are hoisted!).
- [When an arrow function is created](http://www.ecma-international.org/ecma-262/6.0/#sec-arrow-function-definitions-runtime-semantics-evaluation), no name is set up, either (`SetFunctionName()` is not invoked).
## Suport for the `name` property in engines
[In Kangax’ ES6 table](https://kangax.github.io/compat-table/es6/#function_name_property), you can see that no engine currently fully supports `name`, not even Babel. Thus, the code in this blog post shows how things *should be*, not how they are in any single engine.
**Further reading:** “[Callable entities in ECMAScript 6](http://exploringjs.com/es6/ch_callables.html)” in “Exploring ES6”. |
| Shard | 30 (laksa) |
| Root Hash | 9527243733070880230 |
| Unparsed URL | com,2ality!/2015/09/function-names-es6.html s443 |