JavaScript WTF: Six of the Language’s Gravest Design Flaws
Tags: javascript, webdev, computerscience, node
Published: 2020-11-09 17:49:18

Some of us have a perhaps misguided affection for JavaScript; others loathe the idiosyncrasies of a language created in ten days. Either way we're stuck with the parlance of web browsers, the idiom whose very name its creator called a ["marketing scam."](https://www.youtube.com/watch?v=XOmhtfTrRxc&t=2m5s) JavaScript makes us yell. It makes us laugh. Above all, it makes us cry a barbaric `NaN` over the mechanical keyboards of the world.

##

## `==`

_In the beginning was_ `1`_, and_ `1` _was with_ `true`_, and_ `1 == true`_._

Equality lies at the heart of logic, mathematics, and democratic society. JavaScript's equality operator (`==`) breaks the equivalence relation of mathematics in that it performs type coercion when evaluating equality. Yes, `1` is equal to `1` in JavaScript, but it's also equal to `true` and `"1"`.

```javascript
0 == 0; // => true
0 == 1; // => false
0 == "0"; // => true
0 == false; // => true
```

To rectify this original sin of unequal equality, JavaScript also offers the strict equality operator `===`, which considers both type and value. Even the strict equality operator isn't without its quirks (or faults): `NaN === NaN // => false`. In JavaScript some equality operators are more equal than others.

##

## `this`

_A junior developer said, What is_ `this`_?, pointing to his monitor with wide eyes; How could I answer the junior developer? … I do not know what it is anymore than he._

The JavaScript keyword `this` is much like English homograph "set." Its meanings are manifold and depend on context. There are as many ways to bind the value of `this` as there are days in the American programmer's work week, as much as we might wish there were fewer:

1. within a method, `this` is the calling object;
2. within a constructor, `this` is the newly created object;
3. in the global scope, `this` refers to the global object (or is `undefined` in [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode));
4. in event handlers, `this` is the `currentTarget` of the `event`;
5. within a function bound with the `call`, `apply`, or `bind` methods of `Function.prototype`, `this` refers to the first argument of the binding method.

For a language that draws an unusually nuanced distinction between types of nothingness in `null` and `undefined`, the ambiguity of `this` is a curious choice. The global `this` in particular is utterly useless at best and often hazardous, hence its removal in strict mode.

##

## `hasOwnProperty`

_The runtime opened the object at once, while S. and JavaScript watched. It was stuffed with properties, and when it was opened two large prototypes fell out, tied up as you might tie up bundles of firewood. The runtime flinched in alarm. "Try higher up, higher up," said JavaScript, directing operations from above. The runtime, gathering up the properties in memory, obediently cleared everything out of the object to get to the properties up the chain. The runtime's memory was already half full of properties. "Oh, there’s been a lot of definition done," said JavaScript, nodding, "and this is only a small part of it. I keep the larger part of what I have here up the chain."_

JavaScript is the only popular programming language using [prototypal inheritance](https://wikipedia.org/wiki/Prototype-based_programming), often contrasted with [classical or class-based inheritance](https://wikipedia.org/wiki/Class-based_programming). While prototypal inheritance isn't as classy as its counterpart, it's a more powerful paradigm. One can easily build classical inheritance from prototypal, and prototypal inheritance is more naturally suited to [composition over inheritance](https://wikipedia.org/wiki/Composition_over_inheritance).

Unfortunately, the `for in` loop unexpectedly traverses an object's entire prototype chain, not only the object itself. If one were to iterate over the properties of a Goomba, the minutiae of the Nintendo Corporation would follow (provided these minute Nintendoan properties weren't defined with `Object.defineProperty`, added in ES5). To iterate through a Goomba and a Goomba alone, one need check `if goomba.hasOwnProperty(property)`:

```javascript
for (const property in goomba) {
  if (goomba.hasOwnProperty(property)) {
    console.log(property);
  }
}
```

`hasOwnProperty` isn't an original sin like `==` or a source of bewilderment like `this`. It's a guardrail to unintuitive and usually unwanted behavior.

##

## `typeof`

_There is no variable one can declare that is not filled with angst and ambivalence, that is not, in one of those values, the mighty_ `typeof` _an_ `object`_._

The operator `typeof` is the most worthless feature in all of JavaScript. With the precision of a software developer returning from a long vacation and trying to determine where she left off, `typeof`'s return values are often misleading and uninformative:

```javascript
typeof {}; // => object
typeof null; // => object
typeof []; // => object
typeof /abc/; // => object
typeof Math; // => object
typeof new String("abc"); // => object
typeof new Date(); // => object
typeof new Boolean(false); // => object
typeof new Number(1); // => object
typeof new Function(); // => function ;)
```

The highest purpose of `typeof` is to check whether a variable is `undefined`, e.g., `typeof actuallyNotAnObject === "undefined"`. To reference the variable otherwise would result in a `ReferenceError`.

##

## `eval`

_Then, with inviolate curve, forsake our eyes_

_As apparitional as sails that cross_

_Some string of text to be_ `eval`_ed away;_

_\- Till with untrusted code ourselves betray ..._

The `eval` function is JavaScript's four-letter word. It executes any string of code passed to it with the privileges of the caller. When a malicious party has influenced that string, `eval` poses a tremendous security risk. It's not even performant given that it has to invoke the JavaScript interpreter—particularly expensive when interfacing with machine code as in variable lookup.

JavaScript developers may not realize that they're using `eval` "under the hood" when they pass a string of code as an event-listener callback or as an argument to `setTimeout` or `setInterval`. Barring build tools and the onanism of metaprogrammers, code ought to be written as code, not strings.

##

## `;`

_The Semicolon has not left me and I don't believe it will leave me so soon; but I no longer have to bear it, it is no longer an illness or a passing fit: it is I._

Like a well-intentioned simpleton under cover of night, the JavaScript parser covertly inserts semicolons when it encounters syntactic errors due to missing semicolons, often inadvertently changing the code's behavior. (The official [rules](http://www.ecma-international.org/ecma-262/6.0/index.html#sec-rules-of-automatic-semicolon-insertion) of automatic semicolon insertion read like [GPT-3](https://wikipedia.org/wiki/GPT-3)'s attempt at computer-scientific legalese.)

The parser papers over what ought to be errors rather than constraining syntax by design. This degree of freedom causes the semicolon-forgetful JavaScript developer's code to break in surprising ways. The developer only discovers this sort of [nerdwar-precipitating bug](https://github.com/twbs/bootstrap/issues/3057#issue-4106844) at runtime, if at all:

```javascript
clearMenus()
!isActive && $parent.toggleClass("open")
```

Semicolons are tedious; they lack understated beauty; yet with parser so devious, semicolons are one's duty.

### About Us

At [Carrots](https://thecarrots.io) we're building a hiring platform specifically for software engineers. You can connect your GitHub, Stack Overflow, and more to show off so much more than your resume. Our algorithm shows where you rank among world-class talent and surfaces your profile to top companies.