close

DEV Community

Cover image for Function Names in JS Can't Contain Spaces, Right?
Jon Randy 🎖️
Jon Randy 🎖️

Posted on

Function Names in JS Can't Contain Spaces, Right?

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's name property 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 😛'
Enter fullscreen mode Exit fullscreen mode
  • 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"
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

Yes, a function created by using bind has a name containing a space.





written by human

Top comments (1)

Collapse
 
nazar_boyko profile image
Nazar Boyko

The bind one is the sneaky part. Any code that keys off fn.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.