Named Function vs. Variable Function?

twitter logo github logo ・1 min read

Hi guys, I'm reading a JavaScript book and came across this example, but it doesn't fully explain when to use each and what the usecases are other than the fact that named functions are hoisted?

Can someone explain if one is better than the other all the time or what the usecases for each are?

function fun() {
Console.log("Hello from func 1"
}

var fun = function(){
Console.log("Hello from func 2"
}

Both can be used as callbacks etc, to me assigning a variable to a function seems just like a named function? Thanks!

Sorry for lack of formatting, wrote this on my phone. Also couldn't seem to add the image via mobile?

twitter logo DISCUSS (4)
markdown guide
 

The distinction goes a bit deeper than your two examples. MDN provides a good explanation, but I'll give a quick overview:

There are function declarations:

function add(a, b)
{
  return a+b;
}

Function declarations must be named.

There are named function expressions:

const plus = function add(a, b)
{
  return a+b;
};

And there are anonymous function expressions:

const plus = function(a, b)
{
  return a + b
};

As far as I understand, the way you write functions is largely a style choice.

The main differences are:

  • As you know, only function declarations get hoisted, so you can actually use a function that is declared before you declare it in code:
add(1,3); //works
plus(1,3); // ReferenceError: can't access lexical declaration `plus' before initialization
function add(a, b)
{
  return a+b;
}
const plus = function namedadd(a, b)
{
  return a+b;
};
  • Named functions can be used recursively
const fibN = function fib(i)
{
  if(i == 1) return 1; 
  if(i == 2) return 1; 
  return fib(i-1) + fib(i-2);
};

Of course you can also use the variable name (fibN in this example) to make the function recursive.

  • If you name a function then the name is used in stack traces, rather than the variable name.
const err1 = function erroriser()
{
  throw Error('error1');
};

const err2 = function()
{
  throw Error('error2');
};

err1();

// Error: error1 debugger eval code:3:9
//    erroriser debugger eval code:3
//    <anonymous> debugger eval code:1

err2();

// Error: error2 debugger eval code:8:9
//    err2 debugger eval code:8
//    <anonymous> debugger eval code:1
  • Function expresions get semicolons inserted after their closing brace (if there isn't one there).
function foo()
{
}// no semicolon will be inserted

const bar = function()
{
}// semicolon will be inserted
 

hoisting will happen only for named function, not for variable function

 

Hey Rahul, I mentioned that in the post but what does this actually help with? I understand hoisting (I believe) but surely decently written code wouldn't rely on hoisting anyways?

 

Most code doesn't need to rely on it, but it's not unusual to see code that does.

The simplest example of it's usefulness is that it lets you sort your functions by name instead of by what each of them depends on, which is helpful for finding code quickly.

It also lets you do cyclical recursion (that is, two or more functions that from a recursive loop), which is impossible without some form of hoisting, forward-declaration, or multi-pass parsing.

Classic DEV Post from May 29

Is generalization killing creativity in the software industry?

As software gets more and more integrated into our lives, the industrialization of its crafting process becomes inevitable. But the over-generalization of software engineering can be crushing the creative side of programming.

Aaron Powell profile image
Computer Science Student, Software Developer Intern @Arm, Passion for Javascript

Customize your DEV feed to keep up with the frameworks and languages you care about.

Get Started