Jeremy Bernier

Javascript Absurdities

December 08, 2015

Javascript is a funky language. Here are some obvious design flaws:

1. Regex test() method is inconsistent when global flag is set

var pattern = /hi/g;
pattern.test('hi'); //true
pattern.test('hi'); //false

Today at work I spent hours on a witch hunt trying to pinpoint the cause of a bug that was delaying a production release. It ended up coming down to this absurd Javascript quirk within a single “if” statement inside a portion of code that hadn’t been touched in a year.

2. null and undefined

Having separate null and undefined types just adds unnecessary confusion.

The best way to check whether variable is null or undefined is if (varname == null). Using the triple equals (which is preferred in almost every other situation) will not catch both types.

3. typeof

typeof [] //"object"
typeof null //"object"
typeof NaN //"number"

Wtf?

4. NaN != NaN

To check if a value is NaN, you have to use isNaN().

5. arguments inside a function is an “Array-like” Object instead of an Array

This is ridiculous. The convention is to use something like var args = Array.prototype.slice.call(arguments) to convert the “Array-like Object” into an Array (and of course that’s totally clear).

6. Checking deep nested objects is a hassle

Want to check if obj.prop1.thing2.key3 === "hello"? If obj.prop1.thing2 is not an object, then a TypeError is thrown and your code will abort. So you have to check `obj && obj.prop1 && obj.prop1.thing2 && obj.prop1.thing2.key3 === “hello”. Or you can use a try/catch function or use a utility function (eg. using Lodash or writing your own).

7. Math.abs(null) === 0

null <= 0 //true null < 0 //false null == 0 //false

8. No clear sane way to parse integers

parseInt() is not guaranteed to default to base 10, so you have to explicitly pass in 10 as the base.

parseInt('2424blahblahblah', 10) //NaN

The ”+” sign is commonly used to parse integers, but is a little different and has its own pitfalls as well. For example:

+'' === 0 //true
+true === 1 //true
+false === 0 //true

+'2e3' === 2000 //true
parseInt('2e3', 10) === 2 //true

Be careful:

[1,2,3].map(x => {hi: ‘ok’}) //[undefined, undefined, undefined]
[1,2,3].map(x => ({hi: ‘ok’})) // [Object. Object. Object][1,2,3].map(x => {return {hi: 'ok’}}) // [Object. Object. Object]

Jeremy Bernier

Written by Jeremy Bernier who left the NYC rat race to travel the world, work remotely, and make the world a better place.