Since 2015, JavaScript has improved immensely.
It’s much more pleasant to use it now than ever.
In this article, we’ll look at function names in JavaScript.
Methods in Class Definitions
We can define methods in class definitions.
For instance, we can write:
class C {
foo() {}
['ba' + 'r']() {}
static baz() {}
}
We can define class methods with computed property names.
Then we can get their name
property values by writing:
console.log(C.prototype.foo.name);
console.log(C.prototype.bar.name);
console.log(C.baz.name);
As we can see, class instance methods are just methods of C
‘s prototype
.
The class syntax is just syntactic sugar on top of the regular prototypical inheritance model.
Static methods are methods attached to the property.
Getters and setters also have names.
For instance, we can write:
class C {
get foo() {}
set bar(value) {}
}
Then we get the names of these 2 methods with:
const getter = Object.getOwnPropertyDescriptor(C.prototype, 'foo').get;
console.log(getter.name);
const setter = Object.getOwnPropertyDescriptor(C.prototype, 'bar').set;
console.log(setter.name);
We use the Object.getOwnPropertyDescriptor
method to get the property descriptor of our class methods.
And then we can get the getter with the get
property and the setter with the set
property.
They all have the name
property to get the name.
Then the 2 console logs get us:
get foo
set bar
Methods with Symbol Keys
We can create methods with symbol keys.
For example, we can write:
const foo = Symbol('foo');
const bar = Symbol();
let obj = {
[foo]() {},
[bar]() {},
};
console.log(obj[foo].name);
console.log(obj[bar].name);
They also have the name
property.
The first console log logs ‘[foo]’
.
And the 2nd console log logs an empty string.
Class Definitions
Class definitions create functions, so they also has a name
property.
For instance, we can write:
class Foo {}
console.log(Foo.name);
Then Foo.name
is 'Foo'
.
We can also define it by writing:
const Baz = class {};
console.log(Baz.name);
Then Baz.name
is 'Baz'
.
Default Exports
Default exports of functions have names set to default
.
This includes the following:
`export` `default` `function` `()` `{}`
`export` `default` `(function` `()` `{});`
`export` `default` `class` `{}`
`export` `default` `(class` `{});`
`export` `default` `()` `=>` `{};`
Other Kinds of Functions
new Function()
‘s name
property is 'anonymous'
.
This is a bug.
func.bind()
creates a function with a name
value that starts with 'bound'
.
For example, we can write:
function bar(x) {
return x
}
const bound = bar.bind(undefined, 123);
console.log(bound.name);
Then bound.name
is 'bound bar'
.
Generator functions get the name the same way normal functions do.
Function Names Assignment
Function names are always assigned during creating and never changed later.
For instance, if we have:
function createFunction() {
return function() {};
}
const bar = createFunction();
console.log(bar.name);
Then bar.name
isn’t 'bar'
, it’s an empty string.
The name
property doesn’t update after it’s created.
Since it’s anonymous at the beginning, it stays anonymous.
Changing Names of Functions
We can’t change the name
value of functions.
So we can’t write:
func.name = 'foo';
func.name
to change a function’s name to 'foo'
.
However, we can change the name by redefining it.
For example, we can write:
function bar() {}
Object.defineProperty(bar, 'name', {
value: 'foo',
configurable: true
});
Then we get 'foo'
logged if we log bar.name
‘s value.
Conclusion
We can get and set the name of a function in various ways.