I have a somewhat fuzzy definition. "A programming language that has more 'intent' to it."
For example, Rust. The designers had definite ideas about what they were creating, noted the trade-offs, and implemented features based on those decisions.
You can say that about lots of languages - Java, C#, Swift, or if you need to go back 10 years, Java <g />, C, or maybe even Python.
JavaScript on the other hand was cobbled together in a few weeks by some poor fellow who was under impossible deadlines. And it shows. We've all seen the "Wat" video. Programming in JavaScript is a minefield of bizarre phenomena. Function scopes as namespaces. Nutty math. It succeeds in spite of itself because, a. It's rarely used for anything truly important, and b. It runs on the most popular run-time environment on the planet.
Not that you can't do great things with JavaScript. But just about any other language would have been preferable.
No, they don't. All of Wat's complaints against JS, in order of presentation:
> [] + [] ; JS: '', Python: []
Python uses + between arrays for concatenation, just like strings, which I think is reasonable. JavaScript does random crap.
> [] + {} ; JS: '[object Object]' (that's a string, not an object), Python: TypeError.
Again, Python's output here is reasonable, JS's is off the deep-end.
> {} + [] ; JS: 0 (the integer) Python: TypeError
Again, Python's output here is reasonable. JS appears to demonstrate that + isn't commutative, but that's too rosy a picture: in this case, + actually is commutative, as ({} + []) and ([] + {}) are the same string, but without the parentheses we get 0. Yes, the lack of parentheses changes the value JS emits.¹
> {} + {} ; in Wat: NaN, in Chrome/Node: '[object Object][object Object]', in Python: TypeError
Similar to before, Python errors out on the garbage, JS just keep computing ever more insane values.
> [longer example, but boils down to "wat"+1 doing something and "wat"-1 doing something else for comedic effect.
Python TypeErrors on both of these.
Python certainly has its own warts, but they are not as ridiculous as the warts that JS carries around.
¹AIUI, {} + [] is parsed as empty code block, implicit semicolon, unary plus, empty array. The parentheses force the grammar to evaluate the entire thing as an expression, so ({} + []) parses instead as a parenthesized empty object, binary plus, empty array.
> cobbled together in a few weeks by some poor fellow
It was. And then all work has stopped on it, right?
Prototypical inheritance is actually not a bad choice.
The event loop also stood the stand the test of time, it's a great choice for IO heavy environments like the web is.
The weak type system made it possible to bang out code really quickly without much thought thus making it very beginner friendly. Most of its issues can be traced back to this.
every time like clockwork
TypeScript, for instance, is a much better development experience in terms of language constructs, but that only makes the package management situation stand out more.