< I changed my mind about JavaScript.
JS the language is not great, but not horrible. The real problem with it is that the way it's used today, and the way browsers have developed to accommodate that use, is counter to both the spirit of the early web, and the design of its protocols. A web browser is supposed to be a general purpose client for hypertext, and applications are supposed to take advantage of the browser's features: this architecture came to be known as REST (representational state transfer), and one of the most important constraints is HATEOAS (hypertext as engine of application state).
But what happened was that browser use and support for client-side scripting increased at the same time browser hypertext features were stagnating (e.g., no rich type-aware form controls, no way to declare links as asynchronous or fetching hypertext into the current page). So applications started being written as client-side scripts, and that drove browser development in the direction of just being a runtime for client-side programs, in a mutually-reinforcing way.
As a result of that, we no longer have an interoperable meta-client for every web app, we have custom apps and custom protocols that you download and run, just like before the web, but less efficient. Plus, you don't really get any choice about what you download, install, and run; it's just done for you without asking permission. While those programs are sandboxed, the sandbox is frequently leaky, and things like speculative execution attacks mean that nothing is ever really securely sandboxed from the rest of the system.
JavaScript the language doesn't really enter into this. The browser scripting language could have been Scheme (it almost was!), and the ecosystem would still have been just as bad if the same historic pressures were in place.