I don’t like JS and try to avoid it wherever possible. I have written some, but I’m not an expert by any means.
My problems with JS/TS:
Simple to start, but hard to program robustly and defensively. Due to the lack of typing, a lot of the codebases I’ve seen end up with extensive input validation code, which often uses fancy tricks that are hard to parse (unless you already know them). Typescript helps with this, but it is not the same as a proper type system because it is optional. Usually I run into runtime problems due to type errors with library code which doesn’t have types (or has the wrong ones).
The core language is filled with weird edge cases in coercion. jsfuck.com and https://www.destroyallsoftware.com/talks/wat are examples. This doesn’t affect my day-to-day code, but it’s equivalent to C undefined behaviour for me. A bunch of hidden rules that I don’t really want to extensively learn and understand, but which will bite me when writing anything moderately complex. ‘===‘ is good, but I think it’s really easy to miss the extra equals, especially if you write code in other languages a lot.
Lack of standard library (in Nodejs). For quick things, I find Python a lot better. The scant JS standard library has been widely criticised. This is a contributing factor to the absolute explosion in the dependency graph whenever you start pulling in a lot of the common dependencies. IMO, Go and Rust both do a better job despite having comparably easy package mangers.
Although some JS code is easy to read, I’ve seen lots of examples of overuse of functional indirection. Maybe it’s something I will start recognising the patterns once I’ve come across them more, I end up ragequitting JS codebases much more often than other languages. Despite its flaws, Go in a good editor is an absolute joy to understand new codebases.
I’ve found a combination of Python, Go and Rust to be the ideal combination. Each has its flaws, but for any specific use case, I can pick one I’d rather use than JS.