Coercion is a very simple term. It means converting a value from one type to another. However, weird behavior might happen if you don't pay enough attention. If you are a web developer, I'm sure that you are using some type of coercion every day (maybe you are just not aware). As web developers, we need to have a deep understanding of what is going on in our programs. It is not a good indicator when some parts of our code have some sort of magic happening.

Having said that, let's jump to the two types of coercion that exist. The first is explicit coercion. It basically means that you are doing it on purpose or that you are using a Javascript function to convert a value (Type Casting). The second type is Implicit. If you use this type, **congratulations, you might be a magician. This conversion is forced by the rules of how Javascript uses a specific value.

Be careful with using magic

Quiz Time

If you don't get what I'm talking about, look at these two expressions and answer to yourself, what is the value of the variable sum? Paste it in your dev tools console or in the shell of your preference.

const number1 = 5
const number2 = "10"

const sum = number1 + number2
console.log(sum)

The answer is below, give it a second thought - don't cheat!

.

.

.

.

.

.

Do you have the answer already?

.

.

.

.

.

.

Ok, let's continue...

The answer is "510", and it is a string. This magic was an evil deed performed by Javascript. Just kidding, this is a JS normal behavior. We are asking it to "sum" two values, but we are providing one value of type string and one of type number. In order to be able to perform what we asked, Javascript is doing this:

const sum = String(numberA) + number2 //String(5) + "10" = "510"

That is basically a string concatenation, it is the same as if we were writing this

const stringA = "hello "
const stringB = "world"

const sum = stringA + stringB //"hello world"

Javascript doesn't care if we are assigning a "number" to a string value type, it is only interested in the type. This is why it is very important to be very conscious of what we are asking the language and what will happen behind the scenes. It is always preferable that we use explicit coercion. When other people reads our code, it will be easier for them to know what is happening. It's about making it look obvious. This way we can avoid bugs and unwanted behavior.

Let's jump to some common scenarios.

To transform from numbers to strings and vice-versa there are several methods you can use. The first one is String() or Number(). If you implement these, remember not to use  the new keyword preceding Number / String .This will generate an object wrapper.

The next method is using toString(). Keep in mind that this can't be called on a primitive value.

Lastly, to convert strings to numbers you can call Number.parseInt() or Number.parseFloat(). Use these only on string values. If you pass another type, it will first coerce to a String() and could lead to unwanted behaviors. For example, if you send "50px", it will ignore what comes after the number, and it will return 50.

Numbers

When transforming values to boolean. I like these two ways of explicitly coercing any value to boolean. The first is Boolean() and the second is using the unary operator (!!) - the first ! sign to coerce, and the second one to flip the sign-. Personally, I prefer the second one. It is more discrete and Boolean seems redundant to me. Remember, the important thing is that everyone on your team understands the code. Talk with them and establish the way that you will be using to coerce any value to a boolean.

Implicit Coercion

As we explained before, this is what happens when you use a value in a way that the language forces that value to be converted.

Some common places where we could see this behavior are these:

This first example will coerce to a string

someConstant + ""

And on the other side, this will coerce to a number

someConstant - 0

It is super common to have implicit coercions in: if(...), for(...;...;...), while(...), ...?...:..., || / &&.

For example, if we do this:

const truthyValue = 1

if(truthyValue) {
 doSomething()
}

The if statement will coerce the truthyValue to boolean, because 1 is not a boolean. After that, it can evaluate the function. So it is always better to use the following code instead of the last one:

const truthyValue = 1

if(!!truthyValue) {
 doSomething()
}

This way we are explicitly coercing our value. We are letting the readers of our code know what is happening.

Another common scenario is || or &&. When we use these operators we are actually not returning true or false, instead, we are returning the value that results from that expression. Look at this example:

const returnADefaultValue = someValue || 0
const shortCircuit = ifThisIsTruthy && doThis()

In the first line, the first thing that happens is that JS evaluates the left-hand side of the expression. If someValue is truthy, it will assign that value to returnADefaultValue, but if someValue is falsy (0, null, undefined) it will return 0.

In the second line of the code above, we have a similar scenario. If the first part of the expression is truthy, it will evaluate the right-hand side, if it is not, it will assign the value to shortCircuit. These two lines are doing some sort of implicit coercion in order to evaluate the expression and assign a value to the constant.

Loose equals vs. strict equals (== vs. ===)

The difference between these two operators is the following: == allows coercion in the comparison and === does not allow it. Be very careful when using the loose equal. I would say that the go-to should be the strict equality, it is just easier to understand. It "forces" you to do an explicit coercion. Both operators check for the type, but the response differs.

One last tip before I go: Never use loose equals with booleans

"42" == true //false

Why? shouldn't it coerce the "42" to true and then true = true? NO!! Javascript coerces true to 1 and "42" to 42 and then 42 == 1 //false. I know, sometimes JS is confusing, but it is what it is, right?

If you want to dig deeper on this, I recommend you this amazing repository. It is a great equality table that will give you the outcome of some edge cases when compared with: loose equals, strict equals and if statements. It has been very useful for me when in doubt.

Teamwork is the key

This post is not only to give you some insights on Javascript. Neither to be the annoying nerd that gives you these code standards. But to encourage you to explore the language and it's edge cases in a conscious way.

Keep in mind that nothing is written in stone and you should discuss the best approach for your application with your team. Always remember: write code for others, not for yourself. Try to make it easy for people to read and learn what you are coding.