DEV Community

Aaron Powell
Aaron Powell

Posted on

Named Function vs. Variable Function?

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?

Top comments (4)

Collapse
 
mellen profile image
Matt Ellen-Tsivintzeli • Edited

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
Collapse
 
rdutta845 profile image
Rahul Dutta

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

Collapse
 
aaron_powell profile image
Aaron Powell

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?

Collapse
 
ahferroin7 profile image
Austin S. Hemmelgarn

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.