DEV Community 👩‍💻👨‍💻

Cover image for JavaScript Type Conversion & Coercion Explained
Zahra Khan
Zahra Khan

Posted on • Originally published at blog.zahrakhadijha.com

JavaScript Type Conversion & Coercion Explained

To properly write JavaScript, we need to be able to understand what's going on under the hood. Since JavaScript is a dynamically typed language, it has many weird parts. You don't have to specify the type of some value before you use it. It allows you to change the types as you write your code.

Let's say you declare a variable and assign it to a string. Later on, you can decide to change it to a number. As I discussed in my post about null vs. undefined, you can leave a variable empty and initialize it later without specifying it's type. This could create a lot of buggy behavior in JavaScript (aren't we thankful TypeScript exists? 😜)

Type Coercion vs. Conversion is one of the topics that can be hard to understand because the language behaves in strange ways. When comparing the string '28' to the number 28, you'd think that they're the same. When you compare them loosely, '28' == 28 you get that they're the same. But they're not. JavaScript does implicit coercion under the hood which converts '28' == 28 to 28 == 28 which obviously becomes true.

Introduction

To understand Type Coercion, we need to remember that JavaScript generally has two types: Primitives and Objects.

There are 7 primitive data types: string, number, boolean, symbol, bigint, undefined, and null. These are not objects and they don't have built-in methods.

Objects are everything else.

Type Conversion happens in two different ways:

Implicit Coercion

Implicit coercion happens automatically by JavaScript. The compiler goes behind your back and converts a value without you explicitly telling it to. It's completely hidden from you. For example, if you add a string to a number or vice versa, JavaScript will automatically concatenate it to a string. Or if you apply non-numbers to mathematical expressions, they will be converted to numbers. This is called Type Conversion.

Let's look at some code:

const currentYear = 2021
const age = '28'
console.log(currentYear + age) // '202128'
Enter fullscreen mode Exit fullscreen mode

JavaScript converted the number 2021 to a string by concatenating the string '28' giving you a result of 202128 instead of doing an actual calculation.

Another example, WITH subtraction:

let age = '28'
let currentYear = '2021'
console.log(currentYear - age) // the strings are implicitly coerced to 1993 here 
Enter fullscreen mode Exit fullscreen mode

This performed a mathematical calculation and implicitly converted the strings into a number.

Explicit Coercion

Explicit coercion happens when you convert the data type of a value stored in a variable ON PURPOSE (explicitly) with a built-in method. You can visually see it happening in your code. JavaScript has three explicit type conversions:

  1. Number()
  2. String()
  3. Boolean()

You cannot convert a variable to null or undefined. I will only be explaining a high-level overview of the three methods. If you'd like to dive deeper, please read YDKJS as the book goes into a rabbit hole of explaining every bit.

Number()

The Number() method will convert any non-number value into a number. It's a little bit complicated because if you convert Number(true) it becomes 1, Number(false) is 0, Number(undefined) is NaN and Number(null) is 0. 👀

Number() will convert a random string, such as Number('Zahra') to NaN.

let age = '28'
Number(age) // 28 - it will be converted from a string to the number 28

let currentYear = 2021
console.log(Number(age) + 2021) // 2049 - does the mathematical calculation and prints out a number

console.log(currentYear + age) // `202128' - prints out the concatenated string without explicit conversion.

Enter fullscreen mode Exit fullscreen mode

String()

The String() method will convert any non-string value into a string representation. Unlike the Number() method, String() will convert String(null) to 'null', String(undefined) to 'undefined', String(true) to 'true' and String(false) to 'false'.

The String() method can be explicit or it can be automatic if a non-string is used in a way where it will be coerced. The most straightforward thing about this method is that the value stays as it is but the data type changes to a string.

let age = 28 
String(age) // '28'

let coffee = 2 + " cups"
String(coffee) // '2 cups' - it was already coerced to a string beforehand and will stay a string with the method

let nothing = null
String(nothing) // 'null'

Enter fullscreen mode Exit fullscreen mode

Boolean()

The Boolean() method is an interesting one! JavaScript already has boolean keywords true and false but there is a list of values that will ALWAYS be falsy when you force a Boolean() coercion on them:

  • undefined
  • null
  • false
  • +0, -0, and NaN
  • ""

Everything else NOT on this list is considered a truthy value. Let's look at some code:

let emptyArray = [] 
let emptyObject = {}
let emptyFunction = function(){}

Boolean(emptyArray) // true
Boolean(emptyObject) // true
Boolean(emptyFunction) // true
Enter fullscreen mode Exit fullscreen mode

These are all true because they're not on the list of falsey values. The importance of boolean values is in understanding how the value will behave if you coerce it.

Summary

There is A LOT more to this subject and I recommend reading YDKJS to get a deeper understanding of the topic. Even though this subject is a bit confusing (this was a hard blog post to write), it's important to understand the buggy parts so that you understand how JavaScript behaves to write better code.

Yes, we have TypeScript now to eliminate some of these bugs so if you wanted to, you could just start using TypeScript but I find it interesting to learn about these weird parts of JavaScript.

I hope this post helped somewhat! I can be reached on Twitter so feel free to DM if you have questions!

Resources:

  1. YDKJS: Types & Grammar
  2. DEV
  3. MDN
  4. freeCodeCamp

Top comments (0)

Visualizing Promises and Async/Await 🤯

async await

☝️ Check out this all-time classic DEV post