ℹ️ 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.5 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://www.bocoup.com/blog/whats-in-a-function-name |
| Last Crawled | 2026-04-04 08:31:25 (15 days ago) |
| First Indexed | 2024-04-03 08:00:02 (2 years ago) |
| HTTP Status Code | 200 |
| Meta Title | What’s in a Function Name? - Bocoup |
| Meta Description | Every time I contribute to JSHint, I learn a little more about JavaScript. My most recent fantastical knowledge adventure led me to the behavior of the name attribute of function objects. JSHint has an interesting but lesser-known feature: code analysis reports. When used programatically, JSHint will return an object with some data about the code it has analyzed. |
| Meta Canonical | null |
| Boilerpipe Text | Every time I contribute to
JSHint
, I learn a little more
about JavaScript. My most recent fantastical knowledge adventure led me to the
behavior of the
name
attribute of function objects.
JSHint has an interesting but lesser-known feature: code analysis reports. When
used programatically, JSHint will return an object with some data about the
code it has analyzed. This includes (but is not limited to) information about
function objects present in the code:
jshint
(
'function myFn() {}'
);
console
.
log
(jshint.
data
().
functions
);
/*
[{
name: 'myFn',
param: undefined,
line: 1,
character: 15,
last: 1,
lastcharacter: 19,
metrics: { complexity: 1, parameters: 0, statements: 0 }
}]
*/
The most prominent usage of this feature comes from
the JSHint website
itself
which produces a “Metrics” report in real time. For
example:
Metrics
There is only
one
function in this file.
It takes
no
arguments.
This function is
empty
.
Cyclomatic complexity number for this function is
1
.
I learned that this functionality had been implemented incorrectly while
working on an unrelated bug. Even more troubling, I discovered that my entire
understanding of function names in JavaScript was completely wrong. After a few
hours of existential thrashing (“What does it mean to have a name?”, “Am I a
real boy?”, etc.), I decided to research the issue and learn the correct
behavior once and for all. Here’s what I found.
You Thought You Knew…
First off, I should explain how I originally supposed names were assigned in
JavaScript.
I’m used to making one distinction between function objects–whether they are
function declarations or function expressions. The former requires an
identifier, so I would typically consider this a “named function”:
function
myFunction
(
) {
}
…while the latter does not, so I would call this an “anonymous function”:
(
function
(
) {
}());
This line of reasoning makes some intuitive sense because it plays off the
plain-English definitions of words like “named” and “anonymous”. This is
probably why I was not alone in making these mistakes. The truth is: today’s
JavaScript (ECMAScript 5.1, or “ES5” for short) makes no guarantee about a
function’s
name
attribute. A quick review of
the relevant
specification
will back me up; the identifier we so
commonly refer to as the “name” of named function expressions is
only
used to
create an entry in the environment record (just like a
var
statement).
Anything more than that amounts to a platform-specific nicety.
(Cue existential thrashing)
…but You Had No Idea
As it happens, the specification for the next version of JavaScript (a.k.a.
“ES6”,
working draft hosted
here
) formalizes the
initialization of a function’s
name
attribute. Conveniently, it all hinges on
a single
Abstract
Operation
called
SetFunctionName
.
Learning the ins-and-outs of function name assignment is as simple (although
somewhat tedious) matter of studying all references to this operation in the
draft. This is certainly a necessity for platform implementors, but for our
purposes, a few examples should do the trick.
First off, the spec formalizes some of the behavior that we’ve come to expect:
// function form .................... value of `name` attribute
function
myFunc
(
) {}
// 'myFunc;
(
function
(
) {}());
// ''
But it doesn’t stop there! The spec outlines a bunch of situations where a
function expression (which I previously thought of as “anonymous”) should be
assigned a name:
// function form .................... value of `name` attribute
new
Function
();
// 'anonymous'
var
toVar =
function
(
) {};
// 'toVar'
(
function
(
) {}).
bind
();
// 'bound'
var
obj = {
myMethod
:
function
(
) {},
// 'myMethod'
get
myGetter
() {},
// 'get myGetter'
set
mySetter
(
value
) {}
// 'set mySetter'
};
To be clear, though: the new specification only changes the function object’s
name
property in these cases. When it comes to existing ES5 syntax, the
behavior of the environment record remains the same. Only
function
declarations
create a new entry.
This behavior surprised me because, unlike in a function declaration, I didn’t
consider assignment to variables/attributes to be relevant in the creation of
a function object. In ES6, it is! The JSHint team dubbed this behavior “name
inference”. The function object itself isn’t defined with an identifier, but
the runtime takes its initial assignment into account to make a “best guess” as
to what the function should be called.
Finally, ES6 defines a whole slew of new code forms that would be syntactically
invalid in ES5. Some of these further extend the semantics for function name
inference:
// function form .................... value of `name` attribute
let
toLet =
function
(
) {};
// 'toLet'
const
toConst =
function
(
) {};
// 'toConst'
export
default
function
(
) {}
// 'default'
function
*
myGenerator
(
) {}
// 'myGenerator'
new
GeneratorFunction
() {}
// 'anonymous'
var
obj = {
[
'exp'
+
'ression'
]:
function
(
) {},
// 'expression'
myConciseMethod
(
) {},
// 'myConciseMethod'
*
myGeneratorMethod
(
) {}
// 'myGeneratorMethod'
};
class
MyClass
{
constructor
(
) {}
// 'MyClass'
myClassMethod
(
) {}
// 'myClassMethod'
}
That last example surprised me the most–why is the constructor function
assigned the name of the class and not “constructor”? For most class methods,
the “concise” form assigns the name you might expect. Constructor methods are
special because they are essentially references to the class to which they
belong. This is already the case in ES5:
function
MyClass
(
) {}
MyClass
.
prototype
.
constructor
===
MyClass
;
The same principle applies to ES6 classes even though the constructor function
body and the
class
keyword appear in different expressions.
Standard Deviations
With a thorough specification in hand, we were able to revisit the process of
function name inference in JSHint. It wasn’t all roses and lollipops, though;
there were a couple instances were we intentionally diverged from the spec.
Expressions
In many cases, implementors are directed to invoke
SetFunctionName
with the result of an expression (e.g. “Let
propKey
be the
result of evaluating
PropertyName
. […]
SetFunctionName(propValue
,
propKey)
.”). Because JSHint is a static analysis tool, it does not evaluate
any of the code it inspects*. In these cases, we opted to report the function
as having the name “(expression)”.
Unnamed
The specification dictates “If
description
is
undefined
, then
let
name
be the empty String.” This means that functions declared like so:
(
function
(
) {
})();
…should be assigned the name “”. We decided to instead report the name of
such functions as “(empty)”. Because JSHint is a tool intended to assist
developers and not a JavaScript runtime, we’re comfortable re-interpreting the
specification in situations like this. Specifically: the name JSHint assigns to
a function in its report does not raise compatibility concerns, so we felt free
to implement divergent behavior because we feel it is more helpful.
Improved function name inference has landed in JSHint’s
master
branch
; you can expect it in the
next release.
A Function By Any Other Name
I never get tired of reading about the flashy new features coming in the next
version of JavaScript. That said, function names definitely seem pretty passe
compared to generators, classes, modules, and promises. The pessimist might
even argue that this is unnecessary cruft in the language. But as with any good
standard, this new feature is actually a recognition of a real need.
A function’s name is included in error stack traces. In the absence of function
name inference, platforms typically report nameless functions with some generic
stand-in value like “(anonymous function)”. This tends to reduce the usefulness
of stack traces overall. Some profilers and consoles today will recognize a
non-standard property called
displayName
and fall back to that value when
producing stack traces.
Malte Ubl recently advocated for its adoption in
JavaScript library
code
,
and
Ember.js does kind of use it a
little
.
As runtimes implement this behavior, non-standard workarounds like this will
become less necessary. This small change will help developers focus on solving
the problem at hand without worrying about mitigating debugging gotchas. So
while you’re probably not going to see a talk titled “Function Name Inference
In ES6” at any upcoming JavaScript conferences, this small feature is worth
celebrating.
* –
JSHint does do
one kind of neat-o trick by collapsing string
concatenation
operations
,
but that can hardly be called code execution. |
| Markdown | [Skip To Main Content](https://www.bocoup.com/blog/whats-in-a-function-name#main-content)
[](https://www.bocoup.com/)
Primary Navigation
- [Services](https://www.bocoup.com/services)
- [Blog](https://www.bocoup.com/blog)
- [About Us](https://www.bocoup.com/blog/whats-in-a-function-name)
- [Our Team](https://www.bocoup.com/about)
- [Mission & Values](https://www.bocoup.com/about/mission-values)
- [Careers](https://www.bocoup.com/careers)
- [Contact Us](https://www.bocoup.com/contact)
# What’s in a Function Name?
Posted by Mike Pennisi
Nov 25 2014
Every time I contribute to [JSHint](http://jshint.com/), I learn a little more about JavaScript. My most recent fantastical knowledge adventure led me to the behavior of the `name` attribute of function objects.
JSHint has an interesting but lesser-known feature: code analysis reports. When used programatically, JSHint will return an object with some data about the code it has analyzed. This includes (but is not limited to) information about function objects present in the code:
```
jshint('function myFn() {}');
console.log(jshint.data().functions);
/*
[{
name: 'myFn',
param: undefined,
line: 1,
character: 15,
last: 1,
lastcharacter: 19,
metrics: { complexity: 1, parameters: 0, statements: 0 }
}]
*/
```
The most prominent usage of this feature comes from [the JSHint website itself](http://jshint.com/) which produces a “Metrics” report in real time. For example:
> Metrics
>
> - There is only **one** function in this file.
> - It takes **no** arguments.
> - This function is **empty**.
> - Cyclomatic complexity number for this function is **1**.
I learned that this functionality had been implemented incorrectly while working on an unrelated bug. Even more troubling, I discovered that my entire understanding of function names in JavaScript was completely wrong. After a few hours of existential thrashing (“What does it mean to have a name?”, “Am I a real boy?”, etc.), I decided to research the issue and learn the correct behavior once and for all. Here’s what I found.
## You Thought You Knew…
First off, I should explain how I originally supposed names were assigned in JavaScript.
I’m used to making one distinction between function objects–whether they are function declarations or function expressions. The former requires an identifier, so I would typically consider this a “named function”:
```
function myFunction() {
}
```
…while the latter does not, so I would call this an “anonymous function”:
```
(function() {
}());
```
This line of reasoning makes some intuitive sense because it plays off the plain-English definitions of words like “named” and “anonymous”. This is probably why I was not alone in making these mistakes. The truth is: today’s JavaScript (ECMAScript 5.1, or “ES5” for short) makes no guarantee about a function’s `name` attribute. A quick review of [the relevant specification](http://es5.github.io/#x13) will back me up; the identifier we so commonly refer to as the “name” of named function expressions is *only* used to create an entry in the environment record (just like a `var` statement). Anything more than that amounts to a platform-specific nicety.
(Cue existential thrashing)
## …but You Had No Idea
As it happens, the specification for the next version of JavaScript (a.k.a. “ES6”, [working draft hosted here](https://people.mozilla.org/~jorendorff/es6-draft.html)) formalizes the initialization of a function’s `name` attribute. Conveniently, it all hinges on a single [Abstract Operation](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-abstract-operations) called [SetFunctionName](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-setfunctionname). Learning the ins-and-outs of function name assignment is as simple (although somewhat tedious) matter of studying all references to this operation in the draft. This is certainly a necessity for platform implementors, but for our purposes, a few examples should do the trick.
First off, the spec formalizes some of the behavior that we’ve come to expect:
```
// function form .................... value of `name` attribute
function myFunc() {} // 'myFunc;
(function() {}()); // ''
```
But it doesn’t stop there! The spec outlines a bunch of situations where a function expression (which I previously thought of as “anonymous”) should be assigned a name:
```
// function form .................... value of `name` attribute
new Function(); // 'anonymous'
var toVar = function() {}; // 'toVar'
(function() {}).bind(); // 'bound'
var obj = {
myMethod: function() {}, // 'myMethod'
get myGetter() {}, // 'get myGetter'
set mySetter(value) {} // 'set mySetter'
};
```
To be clear, though: the new specification only changes the function object’s `name` property in these cases. When it comes to existing ES5 syntax, the behavior of the environment record remains the same. Only *function declarations* create a new entry.
This behavior surprised me because, unlike in a function declaration, I didn’t consider assignment to variables/attributes to be relevant in the creation of a function object. In ES6, it is! The JSHint team dubbed this behavior “name inference”. The function object itself isn’t defined with an identifier, but the runtime takes its initial assignment into account to make a “best guess” as to what the function should be called.
Finally, ES6 defines a whole slew of new code forms that would be syntactically invalid in ES5. Some of these further extend the semantics for function name inference:
```
// function form .................... value of `name` attribute
let toLet = function() {}; // 'toLet'
const toConst = function() {}; // 'toConst'
export default function() {} // 'default'
function* myGenerator() {} // 'myGenerator'
new GeneratorFunction() {} // 'anonymous'
var obj = {
['exp' + 'ression']: function() {}, // 'expression'
myConciseMethod() {}, // 'myConciseMethod'
*myGeneratorMethod() {} // 'myGeneratorMethod'
};
class MyClass {
constructor() {} // 'MyClass'
myClassMethod() {} // 'myClassMethod'
}
```
That last example surprised me the most–why is the constructor function assigned the name of the class and not “constructor”? For most class methods, the “concise” form assigns the name you might expect. Constructor methods are special because they are essentially references to the class to which they belong. This is already the case in ES5:
```
function MyClass() {}
MyClass.prototype.constructor === MyClass;
```
The same principle applies to ES6 classes even though the constructor function body and the `class` keyword appear in different expressions.
## Standard Deviations
With a thorough specification in hand, we were able to revisit the process of function name inference in JSHint. It wasn’t all roses and lollipops, though; there were a couple instances were we intentionally diverged from the spec.
**Expressions** In many cases, implementors are directed to invoke `SetFunctionName` with the result of an expression (e.g. “Let `propKey` be the result of evaluating `PropertyName`. \[…\] `SetFunctionName(propValue`, `propKey)`.”). Because JSHint is a static analysis tool, it does not evaluate any of the code it inspects\*. In these cases, we opted to report the function as having the name “(expression)”.
**Unnamed** The specification dictates “If `description` is **undefined**, then let `name` be the empty String.” This means that functions declared like so:
```
(function() {
})();
```
…should be assigned the name “”. We decided to instead report the name of such functions as “(empty)”. Because JSHint is a tool intended to assist developers and not a JavaScript runtime, we’re comfortable re-interpreting the specification in situations like this. Specifically: the name JSHint assigns to a function in its report does not raise compatibility concerns, so we felt free to implement divergent behavior because we feel it is more helpful.
[Improved function name inference has landed in JSHint’s `master` branch](https://github.com/jshint/jshint/pull/1971); you can expect it in the next release.
## A Function By Any Other Name
I never get tired of reading about the flashy new features coming in the next version of JavaScript. That said, function names definitely seem pretty passe compared to generators, classes, modules, and promises. The pessimist might even argue that this is unnecessary cruft in the language. But as with any good standard, this new feature is actually a recognition of a real need.
A function’s name is included in error stack traces. In the absence of function name inference, platforms typically report nameless functions with some generic stand-in value like “(anonymous function)”. This tends to reduce the usefulness of stack traces overall. Some profilers and consoles today will recognize a non-standard property called `displayName` and fall back to that value when producing stack traces. [Malte Ubl recently advocated for its adoption in JavaScript library code](https://medium.com/@cramforce/on-the-awesomeness-of-fn-displayname-9511933a714a), and [Ember.js does kind of use it a little](https://github.com/emberjs/ember.js/blob/43423f6acd1abd4ffb0de6afb744d4897ae2f768/packages/ember-metal/lib/logger.js#L20).
As runtimes implement this behavior, non-standard workarounds like this will become less necessary. This small change will help developers focus on solving the problem at hand without worrying about mitigating debugging gotchas. So while you’re probably not going to see a talk titled “Function Name Inference In ES6” at any upcoming JavaScript conferences, this small feature is worth celebrating.
\* – *JSHint does do [one kind of neat-o trick by collapsing string concatenation operations](https://github.com/jshint/jshint/blob/d0b3cfd935c9445f14b37ea9694d8a172a52739a/src/jshint.js#L2335-L2348), but that can hardly be called code execution.*

Posted by
[Mike Pennisi](https://www.bocoup.com/about/bocouper/mike-pennisi)
on November 25th, 2014
#### Tagged in
[web standards](https://www.bocoup.com/blog/tag/web%20standards)
[](https://creativecommons.org/licenses/by-sa/4.0/)
## Contact Us
We'd love to hear from you. Get in touch\!
### Email
[hello@bocoup.com](mailto:hello@bocoup.com)
[About](https://www.bocoup.com/about)[Blog](https://www.bocoup.com/blog)[Careers](https://www.bocoup.com/careers)[Code of Conduct](https://www.bocoup.com/code-of-conduct)[Black Lives Matter](https://www.bocoup.com/black-lives-matter)[RSS](http://feeds.feedburner.com/bocoup)
[](https://fosstodon.org/@bocoup)[](https://github.com/bocoup/) |
| Readable Markdown | null |
| Shard | 196 (laksa) |
| Root Hash | 8192497719605954996 |
| Unparsed URL | com,bocoup!www,/blog/whats-in-a-function-name s443 |