I think that the problems with JavaScript are very obvious to developers who have used multiple languages (aside from PHP). There are far too many unacceptable quirks. It is full of absolutely stupid ideas, like semicolon insertion. Its scoping is poorly designed. In practice, prototype-based OO is inferior to class-based OO. Its type system is not sensible. It lacks proper support for namespacing and modularity (sorry, CommonJS is a hack and nothing more). It does not have a practical standard library. Its development environments and debuggers are quite lacking. And these are just some of its numerous issues.
So for such a small language, it has many critical flaws. This situation is far worse than what we see when dealing with most other languages. And none of those problems that are listed above have to do with the DOM, so disregarding it has absolutely no impact on them.
Actually its scoping is very well defined: javascript has function scoping and a global scope. That's it.
> In practice, prototype-based OO is inferior to class-based OO.
That is plain and simply not true. A shitty object model is inferior to a good object model, but that's got nothing to do with prototypes v classes (as far as I'm concerned, the world would probably be a lot more enjoyable if more language implemented a self-like object model).
> Its development environments and debuggers are quite lacking.
They're already ahead of most non-corporate languages and keep improving at a fast pace.
And ES6 adds block scopes (via `let`, inherited from Mozilla's javascript extensions).
That strays from the original complaint though.
Class-based OO is implementable with prototype-based OO (with some exceptions such as "protected" which are mostly unnecessary when first class functions are available). In practice, this means you need to learn how to use it (unfortunately the quirky way its implemented in JS doesn't help this at all)
CommonJS provides quite excellent namespacing and modularity - its only a hack because it doesn't work in browsers [2]
The standard library is admittedly lacking but there are many libraries that cover this gap, some of them being de facto standard.
Development environment support is pretty good for a dynamic language, with multiple IDEs doing some form of static analysis and completion
Debugging is pretty good, with modern browsers supporting breakpoints, watch expressions, live code editing, logging with object inspection etc. For node you have the v8 debugger and node-inspector providing pretty much the same.
There are far more pressing issues with JS than the ones you mentioned, like the verbose function syntax (mostly fixed in Harmony), lack of coroutines (mostly fixed with Harmony generators), lack of something like ruby's method_missing or python's __getattr__ (fixed with Harmony proxies)...
[1]: an example of a major deal breaker is not having first class functions
[2]: actually, it kind-of does - https://github.com/substack/node-browserify https://github.com/azer/onejs etc.