However, I think that is good to recognize the good things too:
- JS function and object notation is very flexible and nice to work with. Each time that I go back to Java I feel the pain.
- PHP makes JS look nice and consistent by comparison (note I used PHP from v3 to v5... so my comment maybe wrong today)
- Adopting functional constructs for some parts of the std lib was good. Many times I wished to have an equivalent map/filter/reduce in Python (the list comprehension syntax is terrible)
- NPM and small modules receives tons of criticism. But it allowed NodeJs to thrive. Anybody can publish or get a lib with one command. By comparison doing the same for Java was really hard in the past (you needed permission to publish to MavenCentral... and if you were lucky you were allowed after many days of mail exchanges). The situation in other languages is not better: Python package management is a mess of options, Swift package management is not mature enough.
- JS doesn’t have threads... but some languages (eg Dart) moved away from the classic threads constructs to adopt actors. If you did anything with mid complexity using Java threads and dealing with synchronized/wait you start to appreciate the simplicity of async / await.
- Template literals existed in many languages (shell scripting, Perl, etc). But in JS they can be easily extended with template functions.
- I prefer any of the Node web server frameworks over the pain of Java (I worked for many years using servlets, JEE, Spring.. and Java Rest API frameworks).
I’m not trying to do a “what aboutism” argument, just highlighting that besides the limitations there are also good design decisions in the JS ecosystem.