JavaScript function naming

For the record, other people have written about this specific thing. But now I am writing about it.

What’s the difference between the following ways of writing functions in JavaScript?

  1. var hello = function() {};
  2. function goodbye() {};
  3. var somethingElse = function whatever() {};

ES6’s arrow syntax (e.g. myFunction = () => 1 + 1; ) is roughly equivalent to the first snippet, at least for our current purposes.

If you answered “basically nothing” or “isn’t it just a preference thing”, then, yeah, that’s how I think about it in practical terms too. I mean, you shouldn’t be jumping around between these conventions within the same app. Best to just pick one. Not the third one. You might pick the first version because it lets you assign functions to variables just like you’d assign other values to variables, and that just looks neat and appeals to your aesthetic.

But you’ve probably heard of JavaScript’s anonymous functions (like the function you pass as a callback, right?) and maybe weird scope things like hoisting. Hoisting is one of the weirder parts of JavaScript, but it’s got some cool implications when you’re doing OO things like IIFEs. I also find it comes in handy when writing Angular.

Just to get my initial question out of the way,

  1. Assigns an anonymous function to the variable “hello”. This is called function expression, which is to say that “function() {}” is an expression which is evaluated and assigned.
  2. Declares a function named “goodbye”. This is function declaration. It will be hoisted to the top of the current scope.
  3. Assigns a function named “whatever” to the variable “somethingElse”. This is a “named function expression”. It’s messy enough that I’d suggest avoiding it generally, though it’s useful when you need assign a recursive function to an object property.

Functions in JavaScript are a special kind of object, so they have attributes accessed through dot syntax. They have a built-in attribute called “name”. Check it out:

hello.name ==========> undefined

goodbye.name ========> “goodbye”

somethingElse.name ====> “whatever”

Cool, right? But also not very useful. All the functions are called just the same, with parenthesis. The practical difference is hoisting. A hoisted function will be available for use at the top of the scope in which it is declared, even if it hasn’t been “declared yet”. Consider the following code snippet:

firstFunction();

function firstFunction() {console.log(“this is the first function”)};

secondFunction();

var secondFunction = function() {console.log(“this is the second function”)};

Go ahead and paste the above (in one chunk) into your JS console. It should successfully log “this is the first function”, but throw a TypeError on when it hits the third line. This is because firstFunction’s declaration was hoisted up, allowing us to call firstFunction() *before* its declaration.

This is pretty nifty, but it doesn’t it smell a little? As a rule, I usually prefer the flow of my program to be explicit and as well-ordered possible. In functional (ie not OO) vanilla JS, I use the first syntax.

The best use case I’ve found for it is in Angular, thanks mostly to John Papa’s Angular Styleguide. When writing a directive or factory or whatever, you show what functions are available in that segment, but stuff the nitty gritty implementation details down at the bottom of the file. It’s pretty nifty.

That’s the gist of it! JavaScript scoping is a deep subject (read: it’s a mess), but hoisting is an important piece of it. Please let me know if you’ve got any questions or corrections!

Advertisements

Leave a comment

Filed under Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s