I wouldn't say it's primarily a functional language at all, it certainly contains functions and you can use it in a functional way but the same can be said of many non-functional languages.
1) Lexically scoped closures
2) First class functions
And more importantly it's the combination of these two features which allows you to create, on the fly, lexically scoped first class function objects.
This is incredibly useful in many situations and is justification by itself to put up with the uglier parts of the language. If someone is not used to using closures (and let's face it, the vast majority of programmers are not) then it is difficult to appreciate why this would be useful but I'll list a couple of very generic scenarios:
1) It allows the programmer to defer execution of code to a later point whilst allowing a state to be associated with it.
2) It allows the programmer to deal with many small blocking I/O operations concurrently.
These are not remarkable things in themselves however it is difficult to do them programmatically without threads, and once you start using threads you have already lost.
Years ago I was working as a consultant for Lufthansa and was working on a system that dealt with a significant proportion of Europe's air cargo. There were a lot of messages being sent about that we needed to capture and process. The system we eventually developed was a multi-threaded Java application which replaced a single-threaded C application. It worked pretty well and was about twenty times faster than the C one. Having worked with Node.js for over a year now in some similar scenarios I am confident that it would out compete the Java app easily, and with a fraction of the code, perhaps 20-30%.