JavaScript – Why Passing Large Anonymous Functions is Common Practice

functionsjavascript

I have an opinion (which I am sure will be shared by some) that passing anonymous functions which contain more than a few lines of code, as arguments to other functions affects readability and self-documentation drastically, to the point where I feel it would be far better for anyone likely the use the code to just declare a named function. Or at least assign that anonymous function to a variable before declaring the main function

However, many JavaScript libraries (jQuery, d3.js/NVD3.js) just to give a couple of examples, use large functions in this way.

Why is this so widely accepted in JavaScript? Is it a cultural thing, or are there advantages which I'm missing, which would make the use more preferred than declaring a named function?

Best Answer

Three main reasons I can think of:

  1. Parent Scope Access
  2. Privacy
  3. Reduction of names defined in higher scopes

Parent Scope Access: Inline function definitions allow the inline code to have access to variables defined in parent scopes. This can be very useful for many things and can reduce the amount or complexity of code if done properly.

If you put the code in a function defined outside of this scope and then call the code, you would then have to pass any parent state that it wanted to access to the function.

Privacy: Code inside an inline anonymous definition is more private and cannot be called by other code.

Reduction of names defined in higher scopes: This is most important when operating in the global scope, but an inline anonymous declaration keeps from having to define a new symbol in the current scope. Since Javascript doesn't natively require the use of namespaces, it is wise to avoid defining any more global symbols than minimally required.


Editorial: It does seem to have become a cultural thing in Javascript where declaring something anonymously inline is somehow considered "better" than defining a function and calling it even when parent scope access is not used. I suspect this was initially because of the global namespace pollution problem in Javascript, then perhaps because of privacy issues. But it has now turned into somewhat of a cultural thing and you can see it expressed in lots of public bodies of code (like the ones you mention).

In languages like C++, most would probably consider it a less-than-ideal practice to have one giant function that extends across many pages/screens. Of course, C++ has namespacing built in, doesn't provide parent scope access and has privacy features so it can be motivated entirely by readability/maintainability whereas Javascript has to use the code expression to achieve privacy and parent scope access. So, JS just appears to have been motivated in a different direction and it's become somewhat a cultural thing within the language, even when the things that motivated that direction aren't needed in a specific case.