Why Does Javascript Suck?

We all see it. The /r/programmerhumor subreddit is constantly karma-farmed with “Javascript is terrible” memes. Everyone seems to be on the same page; its easy to hate something that is hated by seemingly everyone else. In psychology, this is called the Bandwagon Effect. “The term “bandwagon effect” denotes a phenomenon of public opinion impinging upon itself (sometimes also referred to as “contagion effect”): In their political preferences and positions people join what they perceive to be existing or expected majorities or dominant positions in society. It implies that success breeds further success, and alternatives that appear to enjoy a broad popular backing are likely to gain even stronger support. Perceived public opinion thus gains the quality of a self-fulfilling prophecy. The metaphorical label of this phenomenon dates from late 19th-century American politics and alludes to the wagon in a parade that carries the band and attracts a large crowd of followers marching behind it to enjoy the music.” [1] I believe that many people in the CS community simply accept the fact that “Javascript sucks” because the community has already confirmed it for them. This is risky behavior, even if it might be true that Javascript is the worst programming language to grace our computers. Also, I’ll concede that I was part of this bandwagon for as long as I can remember, but realized finally that I don’t know anything about the actual design and internals of Javascript. So, it’s time to look under the hood and figure out the truth of the matter.

I’ll look at Google’s V8 JS engine, apparently the most pervasive engine in use. It is open source, found at https://github.com/v8/v8. V8 is written in C++ and is used in Google Chrome browser. It implements ECMAScript in accordance with the ECMA-262 standard. The specification for ECMA-262 is found at [2]. EMCAScript itself is a self-proclaimed general purpose programming language, and V8 Javascript is the browser-embedded version of ECMAScript. There have been 10 iterations of the ECMAScript specification, each of which introduced large feature sets, and probably introduced new sets of pernicious bugs that lie in wait to be found by researchers (like every code base, its virtually impossible to avoid, so that comment isn’t meant as a jab towards the V8 developers). In fact, the V8 codebase has a testing suite found at https://github.com/v8/v8/tree/master/test which among other things, looks to include fuzzers for JSON, web assembly, and regular expressions. Unfortunately, most of these files have not been touched in 2-4 years and some of the fuzzers are … questionable. For example, the JSON fuzzer is provided with 2 input files: json and not-json, which respectively contain respectively {“json”: 1} and not json. No doubt, many outside parties have made their own fuzzing framworks for V8 and submitted (or not submitted) any found bugs, but I expected more examples of strange input for this particular fuzzer. The regular expression fuzzer has a more respectable range of inputs which could trigger odd behavior but still, there doesn’t seem to be any kind of generative fuzzing, only static data fed into V8 when the fuzzer is run. For me, this is not a negative strike against the V8 project. There are plently of input-generating fuzzers available to perform this job and the README for this section of the codebase provides instructions on how to get a real fuzzer up and running. “This document describes how to make a new libFuzzer fuzzer for V8. A general introduction to libFuzzer can be found here. In short, libFuzzer is an in-process coverage-driven evolutionary fuzzer. libFuzzer serves you with a sequence of byte arrays that you can use to test your code. libFuzzer tries to generate this sequence of byte arrays in a way that maximizes test coverage.” This text is followed by a step by step guide on getting the libFuzzer up and running, and the document looks to be up to date. +1 to V8, so far, things don’t look so bad.

V8 Javascript (herein referred to as JS) is an object oriented language. Originally, the ECMAScript was designed as a web scripting language, but morphed over time into a general purpose language. I’m not yet sure what effects that has had. Did JS grow up from a scripting language and truly become a general purpose language, or did it become an amorphous blob of fragile features hacked together like the six million dollar man? I don’t know the answer yet, but first its important to understand the difference between a scripting language and a general purpose language. A scripting language is a programming language that is used to manipulate, customize, and automate the facilities of an existing system. In such systems, useful functionality is already available through a user interface, and the scripting language is a mechanism for exposing that functionality to program control [2]. ECMAScript usage has moved beyond simple scripting and it is now used for the full spectrum of programming tasks in many different environments and scales. As the usage of ECMAScript has expanded, so has the features and facilities it provides. ECMAScript is now a fully featured general-purpose programming language [2]. That is, JS has evolved from something you’d use to run a cron job, to something you’d use to write an application. The way JS functions within a browser is pretty intuitive; the browser provides objects that represent items in the window (menus, html elements, etc) and JS can attach code to those objects (if this menu is clicked, run this code). JS is also used on the server side, with the objects now being things like web requests, files, and data sharing mechanisms. This also sounds fine, as long as the transition from a scripting language to a self-proclaimed GP language hasn’t been paved with issues. Sometimes, when a product is designed to do X, and then its forced to do Y, the changes made have to be molded to the old design, and thus are not ideal. This kind of “sideways engineering” or bending the design of a new component to the design of the original product, can cause infinite headaches and result in a terrible mess that wants to be killed with fire. Once again, I don’t know if this is the case with JS yet.

JS has several built-in types: Undefined, Null, Boolean, Number, String, and Symbol. The first values worry me at first glance, could this be the first hint of code smell? In C++, there is the std::nullptr_t type, and in Java we have the void type. I would maybe map these to the Null type in JS, although I’ve never coded in JS extensively so I may be wrong. Even so, the need for Undefined is possibly strange. Exploring this further by consulting our Oracle, Stackoverflow, its stated that “the undefined value is a primitive value used when a variable has not been assigned a value. The null value is a primitive value that represents the null, empty, or non-existent reference.” [3] Additionally, the following quote was found in a reputable JS book.

You may wonder why the typeof operator returns ‘object’ for a value that is null. This was actually an error in the original JavaScript implementation that was then copied in ECMAScript. Today, it is rationalized that null is considered a placeholder for an object, even though, technically, it is a primitive value.

Professional JavaScript for Web Developers
By Nicholas C. Zakas

This seems messy, and further exploration revealed the same sad truth stated a different way, now mentioning that the bug was kept for backward compatibility: “The fact that typeof null returns object is a well known and documented bug in early versions of ECMAScript that has remained for backwards-compatibility.” Bugs in one of the most core components of a language, the built-in type system, scare me. To Be Continued.

  1. https://onlinelibrary.wiley.com/doi/pdf/10.1002/9781118541555.wbiepc015
  2. https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf
  3. https://stackoverflow.com/questions/5076944/what-is-the-difference-between-null-and-undefined-in-javascript

Leave a Reply