 # What you need to know about Javascript's Implicit Coercion Promise Tochi Updated on ・5 min read

Javascript's implicit coercion simply refers to Javascript attempting to coerce an unexpected value type to the expected type. So you can pass a string where it expects a number, an object where it expects a string etc, and it will try to convert it to the right type. This is a Javascript feature that is best avoided.

``````3 * "3" //9
1 + "2" + 1 //121

true + true //2
10 - true //9

const foo = {
valueOf: () => 2
}
3 + foo // 5
4 * foo // 8

const bar = {
toString: () => " promise is a boy :)"
}
1 + bar // "1 promise is a boy :)"

4 * [] // 0
4 *  // 8
4 +  // "42"
4 + [1, 2] // "41,2"
4 * [1, 2] // NaN

"string" ? 4 : 1 // 4
undefined ? 4 : 1 // 1
``````

## Non-numeric values in numeric expressions

### Strings

Whenever you pass a string as an operand in a numeric expression involving either of these operators: `-, *, /, %`, the number's conversion process is similar to calling the in-built `Number` function on the value. This is pretty straightforward, any string containing only numeric characters will be converted to it's number equivalent, but a string containing a non-numeric character returns `NaN`. Illustrated below,

``````3 * "3" // 3 * 3
3 * Number("3") // 3 * 3
Number("5") // 5

Number("1.") // 1
Number("1.34") // 1.34
Number("0") // 0
Number("012") // 12

Number("1,") // NaN
Number("1+1") // NaN
Number("1a") // NaN
Number("one") // NaN
Number("text") // NaN
``````

#### The case for the + operator

The + operator unlike other mathematical operators, performs two functions:

2. String concatenation

When a string is an operand of the + operator, Javascript instead of converting the string to a Number, converts the number to a string.

``````
// concatenation
1 + "2" // "12"
1 + "js" // "1js"

1 + 2 // 3
1 + 2 + 1 // 4

1 + 2 + "1" // "31"
(1 + 2) + "1" // "31"

//concatenation all through
1 + "2" + 1 // "121"
(1 + "2") + 1 // "121"
``````

### Objects

Most Javascript Object conversions usually result in `[object Object]`, For example

``````"name" + {} // "name[object Object]
``````

Every javascript Object inherits a `toString` method, that is called whenever an Object is to be converted to a string. The return value of the `toString` method is used for such operations as string concatenation and mathematical expressions.

``````const foo = {}
foo.toString() // [object Object]

const baz = {
toString: () => "I'm object baz"
}

baz + "!" // "I'm object baz!"
``````

When it's a mathematical expression, Javascript will attempt to convert the return value to a number, if it's not.

``````const foo = {
toString: () => 4
}

2 * foo // 8
2 / foo // 0.5
2 + foo // 6
"four" + foo // "four4"

const baz = {
toString: () => "four"
}

2 * baz // NaN
2 + baz // 2four

const bar = {
toString: () => "2"
}

2 + bar // "22"
2 * bar // 4
``````

#### Array objects

The inherited `toString` method of Arrays work abit differently, it works in a way similar to calling the `join` method of an array without any arguments.

``````[1,2,3].toString() // "1,2,3"
[1,2,3].join() // "1,2,3"
[].toString() // ""
[].join() // ""

"me" + [1,2,3] // "me1,2,3"
4 + [1,2,3] // "41,2,3"
4 * [1,2,3] // NaN
``````

So when you pass an array where it expects a string, Javascript concatenates the return value of the `toString` method with the second operand. If it expects a number, it attempts to convert the return value to a number.

``````4 * [] // 0
4 /  // 2

//similar to
4 * Number([].toString())
4 * Number("")
4 * 0

//

4 / Number(.toString())
4 / Number("2")
4 / 2
``````

#### True, False and ""

``````Number(true) // 1
Number(false) // 0
Number("") // 0

4 + true // 5
3 * false // 0
3 * "" // 0
3 + "" // "3"
``````

#### The `valueOf` method

It is also possible to define a `valueOf` method that will be used by Javascript whenever you pass an Object where it expects a string or numeric value.

``````
const foo = {
valueOf: () => 3
}

3 + foo // 6
3 * foo // 9
``````

When both the `toString` and `valueOf` methods are defined on an Object, Javascript uses the `valueOf` method instead.

``````const bar = {
toString: () => 2,
valueOf: () => 5
}

"sa" + bar // "sa5"
3 * bar // 15
2 + bar // 7
``````

The valueOf method is intended for Objects that are supposed to represent a numeric value.

``````const two = new Number(2)

two.valueOf() // 2
``````

## Falsy and Truthy

I really wanted to make that falsy and trusy

Every Javascript value can be coerced into either true or false. Coercion into boolean `true` means the value is truthy. Coercion into boolean `false` means the value is falsy.

There are a handful of values in Javascript that return falsy values, they are:

1. false
2. 0
3. null
4. undefined
5. ""
6. NaN
7. -0

Everything else is truthy,

``````if (-1) // truthy
if ("0") // truthy
if ({}) // truthy
``````

The above snippets are okay, but it is better practice to be explicit when trying to determine truthiness of a value. Basically, don't rely on Javascript's implicit coercion, even if you feel you know them perfectly.
Instead of the code snippet below,

``````const counter = 2

if (counter)
``````

Any of the below is better practice depending on your requirements

``````if (counter === 2)

//or

if (typeof counter === "number")
``````

This is because for example, you define a function that is supposed to work with numbers

``````
const add = (number) => {
if (!number) new Error("Only accepts arguments of type: number")
}
``````

So if I call the add function with 0, I will always get an unintended error

``````add(0) // Error: Only accepts arguments of type: number

//better check

const add = (number) => {
if (typeof number !== "number") new Error("Only accepts arguments of type: number")
}

``````

## NaN

`NaN` is a special numeric value that is not equal to itself.

``````NaN === NaN // false

const notANumber = 3 * "a" // NaN

notANumber == notANumber // false
notANumber === notANumber // false
``````

`NaN` is the only Javascript value that is not equal to itself. So you can check for `NaN` by comparing it to itself.

``````if (notANumber !== notANumber) // true
``````

ECMAScript 6 introduced a method for checking NaN, `Number.isNaN`

``````Number.isNaN(NaN) // true
Number.isNaN("name") // false
``````

Beware of the global `isNaN` function, it attempts to coerce it's argument before checking if it's `NaN`. For example,

``````isNaN("name") // true
isNaN("1") // false
``````

The global `isNaN` function should be avoided, the way it works is similar to the function below

``````const coerceThenCheckNaN = (val) => {
const coercedVal = Number(val)
return coercedVal !== coercedVal ? true : false
}

coerceThenCheckNaN("1a") // true
coerceThenCheckNaN("1") // false
coerceThenCheckNaN("as") // true
coerceThenCheckNaN(NaN) // true
coerceThenCheckNaN(10) // false
``````

That's most of implicit coercion. If I missed something, please chime in, in the comments below, and thanks for reading all the way.

### Discussion Only case where I like to use type coercion is with null.

There are only two values that `== null` : `null` and `undefined`. Same thing for `undefined`. So it's very useful for when you want to check if your variable holds an actual value and want to avoid an ugly `(variable === null || variable === undefined)`, just do `variable == null`.

nice tip @elarcis

The last thing I recall biting me in JS and I didn't see it mentioned above:

``````3 === new Number(3)  // false
3 === Number(3)      // true
``````

The first one is false because `new` creates a Number object instance which is compared by reference. Value does not equal object reference.

``````typeof new Number(3) // object
``````

The second one is true because it is a function which returns a value type.

``````typeof Number(3)     // number
typeof 3             // number
``````

This is a Javascript feature that is best avoided.

Type coercion is one of the worst parts of JS. I could not even count the number of hours I have wasted tracking down bugs because of this "feature". It is one of the main reasons I avoid the language.

Yeah, object wrappers. They almost never have an advantage over the normal primitives.

Those sort of bugs can truly be frustrating.

I don't know if it actually fits into the implicit coercion stuff, since it is more about optimization, but since ES2015, the signed 64 bit float representation (52 bit of mantissa, 11 bit of binary exponent and 1 bit for the sign) of Number is now no longer the only available representation of numeric values (which was required in order to work with asm.js and Web Assembly).

Modern JS vms like v8 will therefore keep an extra internal flag if it knows that a number is an integer instead of a float throughout the scope and then run the faster non-floating-point calculations on them. To "coerce" a floating point number to such an integer for the rest of the scope, be sure to add `| 0;` to any calculation that may result in an odd result.  