WRONG!
Despite the widespread belief that function names in JavaScript MUST follow the same rules as identifiers - this is not actually true. Sure, when you use the function keyword to define a function then the name you give in the code must follow the naming rules for identifiers i.e. cannot start with a number, cannot contain spaces, can only use certain characters etc. However, it IS perfectly possible for the name of the function to contain spaces - or any other character. A function's name can actually be ANY string at all.
OK... Explain?
When you use the function keyword, the name you provide is used as the function's identifier and is ALSO used to set the name property of the created function - i.e. the function's name. That identifier is then used (scoped) in one of two ways depending on whether you are doing function declaration or function expression. The important thing here is that the function's identifier and the function's name happen to be the same, but are actually two different things. The fact that the language syntax mandates an identifier name here means that most of the time the function's name appears to be following the same rules... but it doesn't have to! There are other ways to set the name of a function:
-
Using
Object.defineProperty- AFTER function creation A function'snameproperty is defined with{ writable: false, configurable: true}- so we cannot set it directly by assigning our value to the property, but we can define it as follows:
function myFunc() {}
Object.defineProperty(myFunc, 'name', { value: 'my custom name 😛'})
console.log(myFunc.name) // 'my custom name 😛'
- Using a property name trick - DURING function creation We can set the name at creation time without a separate step by use a computed property name trick, which leverages how JS infers names for object methods and functions:
const name = 'my dynamic 🎉 name';
const fn = { [name]: function() {} }[name];
console.log(fn.name); // "my dynamic 🎉 name"
But This is Just a Trick That's Useless?
You might think that, but it's actually used in many libraries - usually for making nice names to be appear in stack traces (most modern JS engines will use a function's name property to refer to the function here).
Oh, and JavaScript actually already makes functions with names containing spaces... and you've probably already used this feature without knowing it:
function myFunc() {
console.log('Hello')
}
const func2 = myFunc.bind({})
console.log(myFunc.name) // 'myFunc'
console.log(func2.name) // 'bound myFunc'
Yes, a function created by using bind has a name containing a space.
Top comments (1)
The
bindone is the sneaky part. Any code that keys offfn.name(a DI container, or a decorator that logs the function it wraps) quietly starts seeing"bound myFunc"the moment something gets bound, so a neat trick on the surface is a real footgun underneath.