4

I'm sorry if this is a duplicate, I have read a few posts asking this question but I haven't found a satisfying answer. I am new to JS, I have worked with C and Java. I recently learned about function expressions which, as far as I understand it, are anonymous function declarations that are assigned to some const variable. I don't see what the motivation behind this is/what the possible use of this is/ how could this ever do something you couldn't just do with a function declaration. for example

const example = function (input){
   return 'Am I useless?:' + input;
}

console.log(example('Idk'));

Like this is just like calling a declared function with the same variable, but instead I'm using this variable name (example), which also makes the anonymous function seem pseudo anonymous since it does have a name it can be reference by.

I don't see when this would ever preferable over just a function declaration, yet the CodeCademy course I'm taking repeatedly uses the function expression thing, so I must be missing something.

I really appreciate the help/clarification.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
BrownBoii333
  • 85
  • 1
  • 8
  • The differences are clearly explained here: https://developer.mozilla.org/en-US/docs/web/JavaScript/Reference/Operators/function – Yuck Apr 19 '20 at 02:20
  • [var functionName = function() {} vs function functionName() {}](https://stackoverflow.com/questions/336859/var-functionname-function-vs-function-functionname) – For local variables, the difference is generally about using or avoiding "hoisting" (JavaScript parsers evaluate declarations before the rest of a function's body). That aside, function expressions remain useful when defining methods, since a declaration and assignment can't be in the same statement. – Jonathan Lonowski Apr 19 '20 at 02:24
  • It's still an anonymous function, it just happens to be referenced by something--e.g., throw an error from it and look at the stack trace--which is why you'll sometimes see this pattern but with a named function. – Dave Newton Apr 19 '20 at 02:49
  • It seems like the question in this context would be, why do you prefer declarations for every usecase? You're right that you can pretty much use either one, so this ends up being pretty much opinion-based. In my view, C only has declarations, so you're primed to expect declarations, but otherwise who knows. – loganfsmyth Apr 19 '20 at 03:24
  • @loganfsmyth So does that mean if I wanted, I could go through we development without really ever needing to use function expressions, or are there some types of situations where it is necessary, or at the least very beneficial, to use a function expression, instead of a function declaration. – BrownBoii333 Apr 22 '20 at 00:44
  • In JS a function is callback and/or constructable, and if you're using a function in most cases all something will care about is if it is passed something callable. Function expressions, function declarations, arrow functions, and class/object methods are all different ways of creating callable objects so you can use any of those as long as the function itself doesn't have other requirements, like a class constructor can only be constructed, and an arrow/method can only be called, and if the callback is passed an explicit `this` then choosing an arrow would mean you can't access that. – loganfsmyth Apr 22 '20 at 01:54

2 Answers2

3

TL;DR: No, function expressions aren't useless.


First of all, I would derive the function declarations from function expressions, not inversely. Function declarations are also useful, but they can be replaced by function expressions entirely.

The main difference: function declarations always create variables, while function expressions do not. However, you can still assign them to variables.

The following codes are identical (OK, not perfectly identical, they differ in their hoisting rules):

function foo(bar){
  return 'baz'
}
//Function declarations create variables like how `var` does
var foo = function foo(bar){
  return 'baz'
}

However, function expressions become handy when you don't want to store the function into a var⁠iable.

Examples include:

  • Constant functions:

    const foo = function foo(bar){
      return 'baz'
    }
    
  • Block-scoped functions:

    {
      let foo = function foo(bar){
        return 'baz'
      }
    }
    
  • IIFEs (Immediately Invoked Function Expressions):

    (function (bar){
      //Here we have an encapsulated local scope and the ability to return things
      return 'baz'
    })('foo')
    
  • Callbacks:

    asyncFn(function (){
      console.log('Done!')
    })
    
  • Storing in objects:

    foo[2].bar = function (){
      return 'baz'
    }
    
  • Assigning to previously declared variables:

    let foo = null
    console.log(foo)
    foo = function foo(bar){
      return 'baz'
    }
    

And, although technically all of the above can be solved by using function declarations only, that would result in lots of unnecessary variables and harder-to-read code.


I don't exactly know why Code Academy prefers to use function expressions in your case, but I think that the point is in the const keyword, as it is:

  • Block-scoped
  • Constant
  • Restricts strange quirks that var (and function declarations) would allow
  • Hoisted with temporal dead zone (cannot be accessed before it is declared)
FZs
  • 16,581
  • 13
  • 41
  • 50
  • Thanks for the detailed response. My takeaway is the main use of FE over FD is that the former doesn't store the function as a variable, but why would we care if the function is stored as a variable. Is this for memory management reasons? Also, in a function expression though the function itself isn't stored as a variable, the return value of it would still be stored in a variable right? Also, is hoisting a bad thing? I notice that only function declarations can be hoisted, but is that a bad thing that is to be avoided? – BrownBoii333 Apr 23 '20 at 20:35
  • @TheYungGrandpa Some of these questions are hard to answer/reason about. Hoisting can't be avoided in JS (`let` and `const` are hoisted too, [but differently](https://stackoverflow.com/q/33198849/8376184)), and generally isn't a bad thing, if you don't do idiot things like creating functions or variables with the same name in the same scope or modify its value before the declaration (these are forbidden by ES6 variable types). As JS is a high level language, you also don't have to worry about memory management. FE vs FD: decide which you like, and use that (if you don't need block scope). – FZs Apr 23 '20 at 21:22
-1

Functions are first-class objects in JavaScript. In your programming background from Java or C this is not true.

A use case for storing a "function" in a variable is to pass it somewhere else - e.g. as a callback. In Java you could compare it to a Runnable, but still it is a different concept.

Javascript is crazy if you come from a "proper" programming language! :) Watch that talk by Brian Leroux for some crazy fun.. https://www.youtube.com/watch?v=et8xNAc2ic8

Stuck
  • 11,225
  • 11
  • 59
  • 104
  • 1
    You can pass a regular function as a callback too; that's not a differentiating factor. – Dave Newton Apr 19 '20 at 02:34
  • JavaScript is a proper programming language. Beyond that, good answers ought to answer the questions and avoid unnecessary opinions and implications. – Ben Cooper Apr 19 '20 at 02:34