JavaScript: Not-Not (!!) Anti-Pattern
Tags: javascript, frontend, pattern, antipattern
Published: 2022-05-23 16:48:55

---
title: JavaScript: Not-Not (!!) Anti-Pattern
published: true
description: The Not-Not Pattern (!!), or bang-bang, is a way in JavaScript to do a type conversion. This pattern can have some significant and unexpected side-effects.
tags: JavaScript, Frontend, Pattern, Antipattern
series: JavaScript Issues
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zlucgl7amvhdlcxp6cqy.png
---

The Not-Not Pattern (!!), or bang-bang, is a way in JavaScript to do a type conversion.

`!` means NOT. So ...

* `!true` is `false`
* `!false` is `true`
* `!0` is `true`
* `!1` is `false`

So when converting a value to a boolean, the code inverts it and inverts it again.

## Examples

```javascript
          !!false === false
           !!true === true

              !!0 === false
!!parseInt("foo") === false // NaN is falsy
              !!1 === true
             !!-1 === true  // -1 is truthy
          !!(1/0) === true  // Infinity is truthy

             !!"" === false // empty string is falsy
          !!"foo" === true  // non-empty string is truthy
        !!"false" === true  // even if it contains a falsy value

     !!window.foo === false // undefined value is falsy
      !!undefined === false // undefined primitive is falsy
           !!null === false // null is falsy

             !!{} === true  // an (empty) object is truthy
             !![] === true  // an (empty) array is truthy
```

## In the Real World

If those examples weren't enough to get you to think about this pattern differently, you should know that this pattern **can have some significant and unexpected side-effects**.

A codebase I was working in loaded information on images on the page. We had a process that needed to run if an image was returned. The thought behind this code was that it **should not** run if there was an error.

Six developers and months of time were spent trying to track down a bug. This bug showed up one in every 3,000 times the information on an image was loaded.

## The Code

Patience and persistence on the part of an intern revealed a significant side effect.

```javascript
const image = { name: 'BOB.jpg' };

function checkImage(image) {
  if (!!image) {
    console.log('image exists');
  }
}
checkImage(image);
```

So, the original code looked as you see above. an image object was passed in and if it exists, the `console.log` is run.

## Unexpected Side-Effect

Here's where the side-effect came in ...

```javascript
const image = "ERROR: Authentication Wrong";

function checkImage(image) {
  if (!!image) {
    console.log('image exists');
  }
}
checkImage(image);
```

With the code above, the intern saw that when an error occurred, the Not-Not Pattern saw the error message at true and it tried to process as if there was an image.

## A Solution

The solution wasn't challenging.

We needed a better pattern for checking the `image` object. This is one solution; there can be many more.

```javascript
const image = "ERROR: Authentication Wrong";

function isObject(val) {
  if (val === null) { return false;}
  return ( (typeof val === 'function') || (typeof val === 'object') );
}

function checkImage(image) {
  if (isObject(image) === true) {
    console.log('image exists');
  }
}
checkImage(image);
```

With the code above, the `console.log` does not run.

## Summary

The Not-Not Pattern (!!), or bang-bang, is a way in JavaScript to do a type conversion. This pattern **can have some significant and unexpected side-effects**.

Because of these side effects I am reluctant to use the pattern in most cases and write code that is longer, with more clarity of purpose, and less potential side-effects.