It’s a combination of things. First, JavaScript is a weakly-typed language (don’t confuse this with dynamically-typed). It’s also poorly designed so that, by virtue of weak typing and crazy coercions, it has wildly inconsistent semantics (as I’ve shown repeatedly in my blog). This “looseness” or lack of discipline allows sloppy coding which can bite you in the ass as your codebase grows larger and larger. When your application is relatively small, you can get away with such indiscretions, but imagine trying to track down a problem when your program reaches into tens of thousands of lines of code.

Second, until recently (with ES6), JavaScript had notoriously bad support for modularization and code reuse. Again, poor syntactical design did not help the cause. In older JS code, you’ll find astonishing hacks or workarounds for modularization that would curl your toes. ES6 does improve the situation, but it’s not 100 per cent nor is it rock solid.

Another example is ES6's new class feature. We know it’s just syntactic sugar over object prototypes, but what most may not realize is that ES6's support for “class-based OOP” is half-assed. Private state (properties or member variables) must be “faked” through a variety of techniques, such as programming convention and discipline (prepending variable names with underscore, for example), or regular variables captured by closures.

These are just off the top of my head.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store