I think all of those things are great. I use this when I need a declarative data structure. I use nested scopes when I need a compositional data structure. Otherwise I use pure functions. Which is most of the time.
I love having these three choices and only these three choices. I think class inheritance, promises/async, and other similar features add complexity for little gain.
I used to revel in using fancy features. I was so excited when I found a real need for a DSL in one of my Ruby applications. I built it. I felt like a rock star. Then 12 months later I realized I could have wrote the same code, more understandably, with functions and a few arrays to index data.
You refer to JS core as "poor" and "bad" which are not very descriptive words. I am sure you have material criticisms but what are they? I read every JavaScript critique I see, and so far they mostly boil down to "it's not C" or "it's not Ruby" or "it's not Haskell".
Yah, it's not. It's simpler and unless you are building a compiler or a video game it's often better because of the simplicity.
The problem with JavaScript, IMO, is that people come from other languages, don't actually learn how the JS primitives are best used, and prematurely try to extend the language. See Promises, see classes, see async. These are all features that were only added because the developers couldn't be bothered to learn how to use exactly the features you mention.
You can argue this as bad usability on the part of JS, but the reason it gained so much traction is not just because it was in Netscape....
These are actually amazingly powerful feature implemented in a small space. As a beginner they are incredibly usable. It's only hard for experts coming from C or Ruby, who are the people wrecking the language with extensions. Lispers seem to get it.