Why nobody should write in JavaScript
JavaScript is one of the languages that wasn’t designed properly. In fact, it wasn’t designed at all. It was an afterthought that just slapped into the browser to have some kind of programming. And because Java was a hot subject at that time, it got Java in its name. It has absolutely no relation to Java, except for some syntax similarity and garbage collection.
There were a lot of attempts to make it better and it has become better but it still has all the fundamental issues that almost all script languages have – lack of type system and that makes it unusable to write anything big or complex.
In a language with the type system compiler knows the type of each object and the set of operations that can be applied to each type. When the compiler doesn’t know the type of each object it creates a lot of problems.
The first problem is performance. Because any object can be any type it will execute much slower than the case when the type is already known. For example, let's check this function:
function SomeName(obj, brb) {
return obj.Key + brb;
}
If the JavaScript engine cannot say what types of obj.Key and brb with 100% probability then this operation will go with the most pessimistic case and assume that it can be anything. As a result engine must check the types of objects in runtime and it will be quite slow.
For example, if Key and brb are integers, it is enough to have around 2-3 CPU instructions to do addition. Moreover, the CPU can easily execute it speculatively and also it can be inlined.
But if the type is unknown that engine will generate code that checks the types of both objects and then then decide what operation it will be. It is a much more complex operation and it will require much more instructions and will be much harder to execute speculatively because it depends on many factors.
The second problem is readability. What type of obj.Key? It can be a number or it can be a string. What is the type of brb? It also can be a number or string. Moreover obj.Key can be a number and brb can be a string or vice versa. And it is correct JavaScript.
What will be the result type of that function? It is not easy to tell even in the case when you know types of obj.Key and brb unless you are very experienced with JavaScript. Everybody who wrote anything in JavaScript has their own set of riddles that produce an unexpected result.
The third problem is refactoring. You have another function that uses Key. Is it the same Key as in the function above or is it different? In some cases, your IDE can tell, but in general case, it will be unknown. If you want to rename the Key property in your class to something else, how do you if the Key above is the same or not? When you have a really small codebase it is easy, but the more you (or somebody else) add, the harder it is to tell.
When I teach people to write code I always say that writing code the first time costs nothing. You can consider it free. But maintaining your code is where most of your expenses will be. In the example above you have 2 cases: the Key could belong to your class or not. So you need to rename the Key and then test your application. If everything works fine then you are correct. But there is still a chance that the code you just refactored was executing only in some rare cases and in fact, you just created a new bug.
Somebody can say that there should be documentation, tests, etc. and they will be correct. But documentation may be outdated and there could be no test for that particular case. Or as we all know, in most of the cases there will be nothing at all.
But even in the best case, it will still take a lot of time. Much more than in any language with the type system. Most of the time you will just rename your property, your IDE will find and rename it in every place. Other languages will find these places during the compilation or checking phase.
The fourth problem is bug detection. Imagine that in the example above, a developer just made a mistake and used obj.Key instead of obj.Value. The Key is a string but the Value is a number and brb is also a number and that function is supposed to add Value and brb. But a developer was distracted and typed the wrong thing.
In a language with a proper type system, you cannot add a string to a number and it will generate the error and our developer will immediately understand their mistake and will fix it. But in JavaScript, it is totally fine and it may even work for most of the cases.
Just remember that each error has its cost. Compiler errors are very cheap. Errors that a developer finds are much more expensive. I would say around 10 times more expensive. Errors found by QA cost a few times more than errors found by a developer. But the most expensive ones are errors that your customers found. I would say they are around 100 times more than errors found by QA. So you can see that an error that went into production costs at least 5000 – 10000 times more than an error found by a compiler.
The fifth problem is dynamic stuff. Imagine that in the example above, the JavaScript engine knows the exact type of obj and it can check that object definitely does not have anything named Key. But the engine cannot report an error because in JavaScript it is possible to define stuff dynamically and there is a possibility that the Key will be defined later.
In conclusion, writing JavaScript code is very expensive. It is okay to write a simple check and show a message that the email is not entered. But if you want to write a complex application then JavaScript is one of the worst languages for this.
In my experience, after the codebase reaches about 12Kb, it becomes very costly to maintain and around 95% of the time goes into testing and debugging after next refactoring. And the bigger codebase the more time you spend in debugging and testing. And it is the reason that big JavaScript applications like Gmail are not written in JavaScript. Instead, it is written in a language with a proper type system and then cross-compiled to JavaScript.
I agree that in certain cases JavaScript has some advantages but in my experience, they are relatively small and apply only in certain I would say edge cases. But disadvantages apply pretty much to every line of code and as a result, I think that this language is fine to write less than 100 lines of code. If you are planning to write more then you need to consider other languages.
I hope it helps someone.