I'll give it a shot; functional programming style--some languages enforce it, some languages merely have features that allow for it if the author is disciplined enough to do so (JavaScript is in the latter camp)--generally eschews mutable state and side effects, i.e. a variable `foo` that is declared outside of the function cannot be altered by the function. Some "pure" functional languages restrict all functions to a single argument. This may feel like an unnecessary constraint (and opinions vary), but one thing that can't be denied is that it keeps your methods small and simple; in any case, it can be worked around by applying a technique called "Currying"[1], which is named after the mathematician & logician Haskell Curry, not the dish (also the namesake of the eponymous functional programming language [the mathematician, not the dish]).

Because nothing outside of the function can be changed, and dependencies are always provided as function arguments, the resulting code is extremely predictable and easy to test, and in some cases your program can be mathematically proven correct (albeit with a lot of extra work). Dependency injection, mocks, etc are trivial to implement since they are passed directly to the function, instead of requiring long and convoluted "helper" classes to change the environment to test a function with many side effects and global dependencies. This can lead to functions with an excessively long list of parameters, but it's still a net win in my opinion (this can also be mitigated by Currying).

A side-effect (hah) of this ruleset is that your code will tend to have many small, simple, and easy to test methods with a single responsibility; contrast this with long and monolithic methods with many responsibilities, lots of unpredictable side effects that change the behavior of the function depending on the state of the program in its entirety, and which span dozens or hundreds of lines. Which would you rather debug and write tests for? Tangentially, this is why I hate Wordpress; the entire codebase is structured around the use of side-effects and global variables that are impossible to predict ahead of runtime.

There is much, much more to functional programming (see Monads[2] and Combinators[3]), but if you don't take away anything else, at least try to enforce the no-side-effects rule. A function without side-effects is deterministic; i.e. it will always give you the same output for any given set of inputs (idempotence comes for free). Because everything is a function, functions are first-class citizens, and there are only a few simple data structures, it becomes easy to chain transformations and combine them by applying some of the arguments ahead of time. Generally you will end up with many generalized functions which can be composed to do anything you require without writing a new function for a specific task, thus keeping your codebase small and efficient. It's possible to write ugly functional code, and it's possible to write beautiful and efficient object-oriented code, but the stricter rules of functional style theoretically make the codebase less likely to devolve into incomprehensible spaghetti.

Manning Publications has a book[4] on functional programming in javascript, which I own but haven't gotten around to reading yet, so I can't vouch for it. However, it does seem highly applicable.

[1] https://en.wikipedia.org/wiki/Currying
[2] https://en.wikipedia.org/wiki/Monad_(functional_programming)
[3] https://en.wikipedia.org/wiki/Combinatory_logic
[4] https://www.manning.com/books/functional-programming-in-java...