JS isn't without its flaws, but can we at least put a few fallacies to rest:
> callback hell
There's no reason to be in callback hell if you use an asynchronous control flow library and stick to the standard style of function signatures. I love @caolan's async [1]. In particular, there's a control flow pattern called `auto` that really (IMO) demonstrates some of the power of async programming: it's a full dependency graph resolver [2].
> single-threaded
There's the cluster module, but nevermind that -- you can always just use the child_process library [3] to access spawn() and fork(). Remember those? Processes are a more nautral match for distributed computing than threads anyway.
> lack of strict typing
Strict typing won't make you a better developer, and you can enforce some degree of type correctness with Closure compiler annotations.
[1] https://github.com/caolan/async [2] https://github.com/caolan/async#auto [3] http://nodejs.org/api/child_process.html