Javascript Absurdities

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

**1. [Regex `test()` method is inconsistent when global flag is set](http://stackoverflow.com/questions/1520800/why-regexp-with-global-flag-in-javascript-give-wrong-results)**

```
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](http://stackoverflow.com/questions/17106681/parseint-vs-unary-plus-when-to-use-which)**

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]
```

Comments

Popular posts from this blog

Symlinking