# How to Avoid Common Pitfalls in JavaScript

JavaScript is a powerful language, but there are certain syntactical and behavioral pitfalls in the language that a newcomer may fall for. These pitfalls generally arise due to properties such as type coercion and evaluation methodology of `==`

& `===`

operator. The `==`

and `===`

operators evaluate an expression using the abstract equality comparison algorithms and the strict equality comparison algorithm (more about it in this tutorial: == vs === JavaScript: Double Equals and Coercion

. JavaScript is a weakly typed language. This means that variables can automatically be changed from one type to another while evaluating an expression. Although this is a very powerful feature of the language, it might give rise to some unconventional situations.

## Understanding why these behaviors occur

### 1. Equality of empty arrays

```
> [] == []
false
```

On first look, it sounds ridiculous. An empty array is not equal to itself? But this is not what the above statement actually means. Arrays are stored by references in JavaScript and in JavaScript, the double equal operator returns `true`

only when you're comparing the same instances of the same type. The comparison above actually asks, "Is an instance of empty array equal to an instance of another empty array?" which is definitely `false`

. The statement above is similar to:

```
> var a = [];
undefined
> var b = [];
undefined
> a == b
false
```

`a`

and `b`

are references to two different locations in memory, hence the result is false. However, if both the array instances have been `same`

(like the one below), then the answer below would have been `true`

.

```
> var a = b = [];
undefined
> a == b
true
```

`NOT`

empty array

2. Equality of an empty array and ```
> [] == ![]
true
```

Before understanding what is happening above, we need to understand the concept of *truthy* and *falsy* in JavaScript and how the `!`

(logical NOT) operator works. Values such as `false`

, `null`

, `undefined`

, `NaN`

, `0`

, `''`

and `""`

are considered as falsy. Other values like `true`

, `{}`

, `[]`

, `"foo"`

etc. are considered truthy. The `!`

operator, on the other hand, is defined for *boolean* values only. Any other data type will automatically be coerced into it's corresponding boolean value when operated with `!`

operator.

Here, `![]`

evaluates to `false`

and the comparison actually becomes:

```
> [] == false
true
```

Isn't that supposed to be false, since empty arrays are truthy? That's right but the double equal operator evaluates expressions on certain rules. We're trying to compare an object with a boolean value and JavaScript will implicitly convert the operands to *Number* type. `Number([])`

is `0`

and `Number(false)`

is also `0`

, which evaluates to `true`

since zero is equal to zero.

### 3. Empty array plus empty array

```
> [] + []
""
```

It might look like the sum of two arrays will concatenate them and hence, on adding two empty arrays, one might get another empty array. But that's not the case in JavaScript. As stated in the ECMA language specification, the addition operator either performs string concatenation or numeric addition. Hence, the `+`

is not defined for arrays and JavaScript will implicitly convert arrays into their *string* equivalent and concatenate them. The above expression will become similar to:

```
> [].toString() + [].toString()
""
```

Concatenate of two empty strings yields another empty string and hence the above statement is valid.

### 4. Empty array minus empty array

```
> [] - []
0
```

This case is similar to the previous one. The `-`

operator is not defined for arrays or *strings*. Hence, JavaScript will implicitly convert the arrays into their corresponding *number* type. Coercion of empty array into *number* type yields `0`

. The above expression is the same as:

```
> Number([]) - Number([])
0
```

Zero minus zero is obviously zero, which makes sense.

### 5. Weird array equal weird string

```
> [null, undefined, []] == ",,"
true
```

This is quite weird. When we try to compare a non-empty array with a *string*, Javascript coerces each array element into a string and then joins them by commas. Stringification of `null`

, `undefined`

& `[]`

gives an empty string. Hence, the expression `[null, undefined, []].toString()`

yields `",,"`

.

### 6. Plus empty array

```
> + []
0
```

That's actually not WAT. In Javascript, the unary plus operator is used to explicitly convert the object into a *number* type. So the above statement is similar to:

```
> Number([])
0
```

### 7. Empty array plus empty object

```
> [] + {}
"[object Object]"
```

You might have guessed this one. As seen in on the third item, JavaScript will coerce the array and the object into *string* and then concatenate them. The default conversion for an object type to *string* is `[object type]`

, where `type`

is the type of object. There are different types of objects in JavaScript like `Object`

, `Function`

, `Array`

, `RegExp`

etc. In this case it's `Object`

.

```
> "" + "[object Object]"
"[object Object]"
```

### 8. Empty object plus empty array

```
> {} + []
0
```

Wait! Didn't we just say that JavaScript coerces object and array to *string* on plus operator? This is actually a bizarre edge case of JavaScript. The JavaScript compiler understands this statement a bit differently. It considers `{}`

as an empty code block and `+ []`

as another statement. We saw `+ []`

equates to `0`

which is why the above expression evaluates to `0`

.

### 9. Empty object plus empty object

```
> {} + {}
NaN
```

This one is similar to the example above. Explicit conversion of an empty object into *number* type yields `NaN`

.

*null* and zero

10. The ```
> 0 < null
false
> 0 >= null
true
> 0 == null
false
```

Well, that's frustrating. JavaScript double equal operator and the relational operator are based on the abstract equality comparison algorithm and the abstract relational comparison algorithm. It's just a fancy set of rules to evaluate an expression.

When we compare `0`

and `null`

using relational operators, JavaScript coerces `null`

into its primitive *number* type. When using relational operators the comparison is similar to

```
> 0 < Number(null)
false
> 0 >= Number(null)
true
```

`null`

when converted to *number* type yields `0`

which explains evaluation of the above statements. However, with the `==`

operator, such a comparison doesn't fall into any category of rules defined for evaluation of expression by `==`

operator. Neither `0`

nor `null`

gets coerced and by rule, if such a case occurs, where the comparison doesn't fall into any category, `false`

is returned.

### 11. Math.min is greater than Math.max

```
> Math.min() > Math.max()
true
```

A lot of programming languages define global maximum and minimum values and so does JavaScript, but not with `Math.max()`

or `Math.min()`

. They are, instead, used to return maximum and minimum values within a group of numbers.

When these functions are called without arguments, `Math.max()`

returns `Infinity`

and `Math.max()`

returns `-Infinity`

.

```
> Math.min(1, 2, 3, 4)
1
> Math.max(1, 2, 3, 4)
4
```

JavaScript employes `Number.MAX_VALUE`

and `Number.MIN_VALUE`

for this task and they work as expected.

```
> Number.MIN_VALUE < Number.MAX_VALUE
true
```

### Wrapping up

That's it! If you have anything to add feel free to comment below. You can also check out this handa JavaScript Cheat Sheet to know more about JS.