JavaScript is one of the most loved and hated languages out there. Some, can’t stand the stench of how obtuse it appears to be. Some appreciate the “anything goes” virtues of an interpreted language, and would marry JavaScript given the chance.

Behold: the “hate speech”.

Interpreted languages are too bug-prone

Callback hell, or how easily you can lose track of what’s going on

Awkward equality comparers, ==, === are infuriating

this is a mess

Anything goes. Loose typing, how pretty much everything can mutate into anything without notice

I disagree with most of the above, and I want to spend a few words addressing these concerns.

First of all, the vast majority of these concerns arise from the paradigm shift people experience when developing in JavaScript. Most people are accustomed to a compiler telling them when something is amiss. In JavaScript, however, there is no compiler, JavaScript is interpreted as it is executed. There are a few ways to work around (or mitigate) this concern.

One way to mitigate the impact of not being able to compile your code, is use strict. By the way, MDN is an extensive resource library on JavaScript you are not using enough.

use strict in JavaScript is reminiscent of Option Explicit, back in the Visual Basic 6 days. It’s merely a safeguard against silly mistakes, but it comes in handy.

A more definitive approach to solve the issue is to resort to a JavaScript compiler, such as CoffeeScript, or TypeScript.

I discourage taking this approach. Not only because languages like CoffeeScript tend to be very opinionated about how your code should look like, but most importantly, it isn’t JavaScript, it’s an entirely different language; even though it incidentally compiles to JavaScript.

The notion of using TypeScript is slightly less infuriating, since it’s a superset of JavaScript, rather than a different language.

Having said that, the fact that both compilers output pure JavaScript remains, which is reason enough to learn how to code in JavaScript properly by yourself, rather than have a layer of abstraction making coding style choices for you. It’s not like JavaScript is MSIL. MSIL is really hard to read, maintain, write, and everything in between, and generally not worthwhile to code in, unless you need to fine-tune performance, dynamically generate classes, or the like.

JavaScript is not thatobscure. JavaScript can be learnt. Compilers hinder your ability to do that. You should learn what a closure is. How to extend a prototype. How to use callbacks sensibly. There lies the real beauty of JavaScript code.

Demystifying JavaScript

Interpreted languages are too bug-prone

While it might be true that JavaScript code is harder to debug, and can definitely be harder to maintain when improperly structured. There are several tools at our disposal to prevent chaos.

You should treat JavaScript as you would any other language, and as such, you should Unit Test your code. There are severalframeworkstopickfrom.

Client-side JavaScript might prove harder to structure than JavaScript in Node.JS. Frameworks like Backbone.js and Knockout.js can help you structure your code cleanly and without making an unmaintainable mess out of it.

Awkward equality comparers, == is infuriating

This one I’ll concede. The equality operators, == and != are a mess… They try too hard. If the values being compared are of different types, these operators will attempt to coerce these values using complicated rules that are not even transitive. Avoid them entirely. Use, as Crockford puts it, the “good operators”: === and !==. These return false in case of type mismatch, as would be expected.

Now compact is a four-wheel car, while our Window became a truck, and suddenly has 10 wheels. Furthermore, this can be chosen through Function.prototype.apply, and otherwise changes depending on the context it’s being evaluated in.

Well, you have two options. One option is to ignore the damn thing, and don’t use this or new, after all, ignorance is a bliss. The other option is, you guessed it, learning how it works.

Anything goes. Loose typing, how pretty much everything can mutate into anything without notice

This one is, in my opinion, one of the biggest selling points in favor of JavaScript, which is more often confused with a drawback against the language. I’d rephrase this as JavaScript just works, in that whatever change you want to introduce to your code, JavaScript can accomodate. And as long as you are conscious about maintainability, such flexibility shouldn’t become a problem.

There are many oddities like this in JavaScript, more than in some other languages such as C#, fewer than in others. Most of these oddities are easily avoided, and their persistance stems from poor implementations in some web browsers. Others (such as for..in problems), simply come from the nature of a prototypal inheritance model.

Poor support for (classical) debugging, such as reasonable stack traces

Often overlooked is the ability to execute code on demand in a browser console, or writing debug messages which you can see in real time with no extra frameworks, and without altering the user experience. These are things you often can’t do in other languages either, once you get accustomed to these, you’ll find it way more productive to debug with a console and hacking away at the DOM, than to step through your code, and recompiling every time you add a comma.

Prototypal vs Classical inheritance

In JavaScript, things inherit from other things, and not from abstract concepts (or classes). This might be hard to wrap your head around if you are experienced in class-based languages such as Java or C#, but you’ll soon get over it, and begin reaping the benefits.

Comments(4)

I saw this post on EchoJS tonight and felt compelled to comment because I’m not sure I’ve ever seen hiragana used as bullets before. I’d like to expand on your “anything goes” point a bit. For me, the power of JavaScript comes from its lack of much structure. “Classical” inheritance systems often rely on maintaining a rigid, formal structure between classes in an inheritance hierarchy, where classes can most often only be functionally modified at compile-time, discounting things like lambdas and so on. There’s some benefit to that, for sure. Sometimes it’s advantageous. But JavaScript is so interesting to me precisely because, although it it eschews that formality, it is not any less brittle for it. And, beside that, it’s easy to augment the built-in inheritance system with your own conventions, a-la Crockford’s “parasitic inheritance” or whatever he calls it.

I’m not a huge fan of any of the compile-to-JavaScript languages, but I’m glad they exist. I’d rather just write JavaScript. It’s not a perfect language, though there’s really no such thing. I write a good amount of PHP code at my day job—for me, writing JavaScript is just more pleasant.

JavaScript is not that obscure. JavaScript can be learnt. Compilers hinder your ability to do that.

This IMHO this is just wrong, compilers are your friend, on a code base of 100k+ lines of code the compiler can verify the integrity of your application without having to discover it at runtime. Further the compiler can perform optimization which you don’t need to be aware of.

The notion of using TypeScript is slightly less infuriating, since it’s a superset of JavaScript, rather than a different language.

Important to note here that TS is just JavaScript and one its major selling points is that its trying to give you the JS of the future now. Language features such as classes & modules in ES6 are a way for developers to avoid writing the verbose javascript they normally would.

You should treat JavaScript as you would any other language, and as such, you should Unit Test your code.

I agree with this but 100% coverage is unrealistic for most teams and I would argue a waste of effort.

Awkward equality comparers, == is infuriating

“this” is a mess

You seem to agree they are broken, so not going to argue that. The point is they are probably the most important features of a language. If you can’t get that right then the whole language is in trouble.

Anything goes. Loose typing, how pretty much everything can mutate into anything without notice

This is not good at all on large pieces of software. Mutability has been proven to introduce bugs, especially as we move to a world with more concurrency. JavaScript is not going to scale well in this aspect AFAIC.

Nonsensical behavior like parseInt(‘08’) === 0

Agree just avoid.

Often overlooked is the ability to execute code on demand in a browser console, or writing debug messages which you can see in real time with no extra frameworks, and without altering the user experience. These are things you often can’t do in other languages either, once you get accustomed to these, you’ll find it way more productive to debug with a console and hacking away at the DOM, than to step through your code, and recompiling every time you add a comma.

This is so far what is expected of moderm debuggers its laughable, what about when you work with webworkers, what about drill down into debug values? Also many static languages support console.log in some format. c# has debug.WriteLine() which you can view using a tool like DebugView. On “Recompiling” well yes with C# or Java you do, but with TypeScript for example you can just save the file and continue. The compiler does not have to be in your way.

Prototypal vs Classical inheritance

Yeah agree with you on this, two different approaches and they differ slightly. However in classical inheritance you can use polymorphic behavior on base types. In JavaScript its structural and this leads to nasty little hacks. Classical inheritance for the win! :-)