26

I was reading that using anonymous functions in javascript is bad practice, because it can make debugging a pain, but I haven't seen this for myself. Are anonymous functions in JavaScript really bad practice and, if so, why?

palswim
  • 10,910
  • 6
  • 47
  • 72
stevebot
  • 21,481
  • 26
  • 107
  • 176
  • Developer tools and build/module strategies have come a _long_ way since 2010 .. Chrome / WebKit are really good, FireBug is so-so but adequate (and naming the function expression can help visually as well). Anyway, considering the sheer number of times they are used this is a .. dubious axiom, possibly tied to code that was "too clever" and hard to follow/debug to begin with .. because I've never felt pain debugging _my_ code ;-) – user2864740 Feb 11 '15 at 18:59

6 Answers6

19

I am going to go against the flow a little here and make the case that anonymous functions are indeed bad practice even though they are widely used.

1) Anonymous functions cannot be reused.

2) Anonymous functions, by definition, do not have a name and so do not describe what they do. Which is to say the code is not self documenting.

3) Anonymous functions cannot be tested in isolation with a unit testing framework.

4) I personally think they make code more difficult to read and debug. Though your experience may vary.

I do think there are situations where an anonymous function is the best choice and as a general rule in order to avoid the above downsides I almost always name my functions.

Typically the longer your anonymous function becomes the more likely that it would benefit from having a name.

bhspencer
  • 11,362
  • 4
  • 29
  • 38
  • 2
    1) Anonymous functions and closures can be re-used, every function is value and can be assigned to a variable or supplied as a function argument - it is just a matter of exposing function-object such at the right level/scope; 2) Anonymous functions (or function expressions) _can_ be given explicit names but are "anonymous" in context; 3) Depends on what is tested, how it is tested, and how the function objects are exposed; 4) Closures/lambdas _can_ be abused in "too much cleverness" cases, but _terrible coders are terrible coders_, even with the most trivial procedural code statements .. – user2864740 Feb 11 '15 at 19:04
  • 1
    I am confused by what you say here. If you give a function a name and assign it to a variable isn't it by definition not an anonymous function? Could you give an example of anonymous with a name? – bhspencer Feb 11 '15 at 19:08
  • The problem is the term "anonymous" function is a lie. The real term should be *function expression* or *closure* or even *lambda* (this differs from a top-level "function statement" or "method"). Because how can one use an "anonymous" function (except an IIFE) without *some* name given to it? – user2864740 Feb 11 '15 at 19:09
  • I think the term "anonymous function" is well understood by the community. It means a function that is not assigned to a variable. – bhspencer Feb 11 '15 at 19:10
  • But that broad view is confusing and generally incorrect. Consider this: `[].forEach(function () {..})` - that function *has* a name it is bound to. Or, likewise, is this still "anonymous" - `var filter = function () { .. }`? The problem is "anonymous" is a poor term. – user2864740 Feb 11 '15 at 19:11
  • 2
    I disagree. In your example the function passed into the function called forEach does not have a name. – bhspencer Feb 11 '15 at 19:12
  • It does have a name - the name of the parameter binding from context. It is not more or less "anonymous" at the _binding site_ than `[].forEach(doIt)`. – user2864740 Feb 11 '15 at 19:13
  • 1
    I agree it is assigned a name when it is later used but it doesn't have a name in the context that it was created in. It is in the context that it was created in where my 4 points listed above stand. – bhspencer Feb 11 '15 at 19:17
11

Nope, anonymous functions are used all over the place in JavaScript across the web. It may make debugging a little more difficult in spots, but not nearly enough to say that they shouldn't be used.

For example, JQuery makes extensive use of them.

There are a lot of times when you want to use them over formally declared functions, such as when you want to limit their scope.

ColBeseder
  • 3,309
  • 3
  • 25
  • 45
kemiller2002
  • 107,653
  • 27
  • 187
  • 244
  • 10
    Actually, this is one reason I've stopped using jQuery. It always took far longer than I thought reasonable to determine whether a bug was a syntax error in my code, a logical error in my code, or something wrong with jQuery itself. You have to admit, a call stack of anonymous functions doesn't make things as terribly clear at-a-glance as one of named functions does. – Kev Aug 11 '10 at 20:12
  • 6
    You can always use a [named function expression](http://yura.thinkweb2.com/named-function-expressions/#named-expr). – Marcel Korpel Aug 11 '10 at 20:18
7

I would say the contrary, lambdas ( alias ) make some expressions much more succinct. If you're binding multiple event handlers to multiple events it would be tedious giving a function name to each and every event handler, for example.

It's more helpful and time-conserving than not, even if it makes debugging a little bit harder but I rarely struggle with debugging because a function is anonymous. And you should use JSLint to make your life easier when coding.

meder omuraliev
  • 171,706
  • 64
  • 370
  • 423
4

Most definitely not, lambda functions are used all over the place, almost ubiquitous.

Jacob Relkin
  • 151,673
  • 29
  • 336
  • 313
  • 24
    Just because something is _common_ doesn't mean that it's _correct_. There may be nothing wrong with using anonymous functions, but saying, "Everybody does it" does not constitute a valid argument. – Ian Dunn Jun 25 '11 at 16:22
  • deeply nested sass is all over the place, but it's completely wrong – Toni Leigh Oct 02 '15 at 09:26
4

Just because everybody uses them doesn't make them good practice (everybody remember using the table element for layout?). But, they're great because they can help clarify and simplify your code, giving less opportunity for something to go wrong.

But, anonymous functions shouldn't be so complicated that debugging becomes difficult with them. In that case, perhaps it's better to make a new function.

palswim
  • 10,910
  • 6
  • 47
  • 72
  • 3
    You can always use a [named function expression](http://yura.thinkweb2.com/named-function-expressions/#named-expr). – Marcel Korpel Aug 11 '10 at 20:16
  • 1
    @MarcelKorpel: That link you provided has died, but I assume you mean you can optionally add a name to your anonymous function (making it no longer anonymous) like this: `var fAnonymous = (function nonAnon(){ });`. This could certainly help with debugging. – palswim Feb 26 '16 at 18:53
  • @palswim Indeed. For the record, the article I linked to is now on [Kangax' site on Github.io](https://kangax.github.io/nfe/#named-expr). – Marcel Korpel Feb 27 '16 at 12:37
0

Here is my browser console:

// Bad
poopy = function(){}
// function (){}
groupy = poopy;
// function (){}

// Good
droopy = function loopy(){};
// function loopy(){}
floupy = droopy;
// function loopy(){}   

Imagine you are debugging something and you have a function name called groupy. You type it's name to get more information on it. If that function has been set as in the bad section, you have no idea of what the original declaration was. If however, you define your function name, as in the Good section, then you will always have a trace of the original function name.

unflores
  • 1,444
  • 14
  • 29
  • 2
    Your answers will be much clearer if you use identifiers that describe their function in the example, rather than classic ```foo``` and ```bar``` identifiers. My eyes glazed over after the third rhyme. – Wes Modes May 01 '18 at 18:03
  • Above comment is true, but it doesn't make OP's answer wrong – knickum Nov 15 '19 at 19:36
  • @knickum Op only has a question....I don't see an answer. I am specifically responding to the point that OP mentioned they hadn't seen a problem debugging with anoynmous functions. If you can pass a function around, it can be called anywhere, debugging a stacktrace that has a function name in it is a million times better than doing so without because you won'thave any other way to locate it in that case. – unflores Nov 24 '19 at 22:30
  • @WesModes ugh, maybe I shouldn't have gone with rhyming...but the function of the functions(hehe) have no importance, it is litterally all about whether the names show or not. – unflores Nov 24 '19 at 22:31
  • I'm referring to @unflores as OP, as it is your answer that started this comment thread. So I'm agreeing with the other commenter (Wes Modes) that the rhyming doesn't help, but I'm also saying that doesn't make your answer wrong. – knickum Nov 26 '19 at 16:30