DEV Community

loading...
Cover image for Type coercion in JavaScript
LogRocket

Type coercion in JavaScript

Matt Angelosanto
Managing editor for the LogRocket blog. I didn't write the post you just read. To find out who did, click the link directly below my name.
Originally published at blog.logrocket.com ・6 min read

Written by Leonardo Maldonado ✏️

Type coercion, type conversion, typecasting, and type juggling: all different names that refer to the process of converting one data type into another. This process is present in almost every programming language and is an important concept in computer science.

While JavaScript is known as one of the easiest programming languages for beginners, it can also become frustrating when developers expect JavaScript to do one thing and it returns another.

And while the ECMAScript Language Specification standard is available to developers to help guide them through these issues, not reading and understanding the specification standard can cause more frustration when dealing with type coercion in JavaScript.

Type coercion in JavaScript is an example of how the language can produce unexpected results when we don't know exactly how it works. Everyone who has touched even a little bit of code in JavaScript can relate that type coercion can be tricky.

While the code examples we cover in this article may seem like bugs that a version update could fix, the reason we review why type coercion acts the way it does is because many legacy products and code depend on older versions of JavaScript.

This means that creating changes to the language can break legacy products and code, and we must instead learn how to navigate the quirks of type coercion.

In this post, we’ll cover what types are in JavaScript and how to use type coercion, setting us up for programming success.

Types in JavaScript

We can refer to JavaScript as an untyped language, which means that it has no static types. However, the prominent myth that JavaScript doesn’t have types is false.

JavaScript has seven primitive types:

  • string
  • number
  • Boolean
  • undefined
  • null
  • Symbol
  • BigInt

Variables in JavaScript don't have types, however. Whenever we use the typeof operator to return a variable type, we return the variable’s value type.

Now that we have cleared up a few misconceptions about JavaScript and types, we can learn more about type coercion and how it works in JavaScript.

Type coercion

Type coercion in JavaScript only coerces to the string, number, and Boolean primitive types. There's no way in JavaScript to coerce a value type to object or function.

JavaScript has two characterized forms of coercion: implicit coercion and explicit coercion.

Implicit coercion happens when JavaScript coerces the value type to the expected type under the hood. This type of coercion happens without the developer noticing.

Explicit coercion happens when we want to coerce the value type to a specific type. Most of the time, explicit coercion in JavaScript happens using built-in functions such as String(), Number(), and Boolean().

When we try to create operations in JavaScript using different value types, JavaScript coerces the value types for us implicitly.

This is one of the reasons why developers tend to avoid implicit coercion in JavaScript. Most of the time we get unexpected results from the operation if we don't know exactly how JavaScript coerces the value types.

Implicit coercion is not as bad as developers tend to think, and in fact, is useful for writing readable but efficient code. The key to properly understanding how implicit coercion works in JavaScript is to understand what it is doing under the hood.

Number

There are many possible ways for coercing a primitive type to a number. The Number() function coerces the value type that passes to the function, then to a number. When a type can't be coerced to a number, the returned result is NaN.

Let's look at a few examples of explicit coercion using the Number() function:

Number("42"); // 42
Number(""); // 0
Number(true); // 1
Number(false); // 0
Number(null); // 0
Number(undefined); // NaN
Enter fullscreen mode Exit fullscreen mode

We can clearly see some obvious and unexpected results. Converting null to a number returns 0 while converting undefined to a number returns NaN. Both operations should return NaN since both value types are clearly not valid numbers.

Converting an empty string to a number returns 0. This is another weird part of JavaScript because this value type is clearly not a valid number yet it still converts to 0.

Kyle Simpson, the creator of the You Don't Know JS book series, said, “Empty string becoming 0 is the root of all coercion evil.”

Although the results that we get from the Number() function may seem unexpected, the ECMAScript specification clear states these discrepancies. But without reading the ECMA specification, developers may not realize this is just how JavaScript is written.

In our first example, we received different results for null and undefined. The ECMAScript specification Number()function with a null value type it returns 0, and whenever we use the same function with undefined it returns NaN.

ToNumber is a type conversion name that the ECMAScript specification uses when referring to an operation where a value converts to a number. Number() is a primitive wrapper object in JavaScript that converts a value to a number. This is the same with ToBoolean, which we will cover later.

Below is a list of arguments and the result the ToNumber operation converts them to:

Table In EMCAScript Documentation Showing ToNumber Table

In our other example, we used the Number() function with an empty string and received a 0. This is something that is explicit in the ECMAScript specification as well:

A StringNumericLiteral that is empty or contains only white space is converted to +0. – ECMAScript 2015 Language Specification

String

To explicitly coerce a value to a string in JavaScript we can use the String() function. To implicitly coerce a value to a string, we can use the + operator with any operand that is a string.

The primitive types convert to strings as expected:

String("42"); // "42"
String(true); // "true"
String(false); // "false"
String(null); // "null"
String(undefined); // "undefined"
Enter fullscreen mode Exit fullscreen mode

We should be careful when using type coercion when we want to create an operation and one of our operand types is a string.

JavaScript returns our operation as a string when the correct way of handling the operation should be throwing an error because there's no way to make a mathematical operation using a number and a string, which is not a valid number:

10 + "10" // "1010"
20 + "200" // "20200"
0.212 + "1" // "0.2121"
Enter fullscreen mode Exit fullscreen mode

Boolean

To explicitly coerce a value to Boolean in JavaScript, we can use the Boolean() function. To implicitly coerce a value to Boolean, we can use logical operators, such as ||, &&, and ! in a logical context.

The specification of the Boolean() function is very clean and helpful. We can clearly see which results we receive depending on the value type that we pass:

Table In The EMCAScript Documentation Showing ToBoolean Values

The list of falsy values is easy to remember. Everything that is not on the list is a truthy value:

Boolean('') // false
Boolean(0) // false     
Boolean(-0) // false
Boolean(NaN) // false
Boolean(null) // false
Boolean(undefined) // false
Boolean(false) // false
Enter fullscreen mode Exit fullscreen mode

As stated before, logical operators also coerce a value type to a Boolean:

true && false // false
true && true // true
true || false // true
true || !false // true
"name" || 0 // "name"
"name" || [] // "name"
"" || [1, 2, 3] // [1, 2, 3]
Enter fullscreen mode Exit fullscreen mode

Conclusion

Type coercion is a core JavaScript concept used across every application, API, and service using JavaScript.

In all, unless you pursue explicit coercion, JavaScript implicitly coerces depending on the value types and operation used. But regardless of using implicit or explicit type coercion, it provides developers flexibility and helps make the code more readable.

This short overview provides the basics in understanding type coercion, however, reading the ECMAScript specifications can provide a more in-depth review of the concept to understand why unexpected type coercion results occur.


LogRocket: Debug JavaScript errors easier by understanding the context

Debugging code is always a tedious task. But the more you understand your errors the easier it is to fix them.

LogRocket allows you to understand these errors in new and unique ways. Our frontend monitoring solution tracks user engagement with your JavaScript frontends to give you the ability to find out exactly what the user did that led to an error.

LogRocket Dashboard Free Trial Banner

LogRocket records console logs, page load times, stacktraces, slow network requests/responses with headers + bodies, browser metadata, and custom logs. Understanding the impact of your JavaScript code will never be easier!

Try it for free.

Discussion (0)