Converting data types in JavaScript with simple examples

JavaScript is a dynamically typed — also known as untyped — language. Typing is the process of defining the data type of a variable. In dynamically typed languages, typing is associated with the variable’s value and not the variable itself. Thus, in JavaScript, variables don’t need to specify a certain data type when they are declared.

The five variable can be of type of String or Number, or any other type for that matter.
(click on the image to open in a new tab)

The variable five in the example doesn’t specify the data type. We can assign a String value or a Number, or any value for that matter later on.

In a statically typed language, the variable declaration statement first states the data type of the variable, followed by its name. Bellow is an example of the statically typed language Java.

Here, the Java variable age, is defined as integer.
(click on the image to open in a new tab)

Here, the age variable can only be an integer.

JavaScript, on the other hand, tackles the issue of type later, after a value has been assigned to the variable.

Type Conversion

In computer science, there are different ways of changing an expression from one type to another.

Let’s see some extreme examples of type conversion in JavaScript.

A small collection of some very special irregularities in JavaScript.
(click on the image to open in a new tab)

We see that JavaScript automatically converts types in the above operations.

Regarding the last one. The strings are converted into numbers and then the subtraction of a negative number is equivalent to adding the positive version of that number.

Examples like the above are available in wtfjs.com.

The ability to convert data types is fundamental to all programming languages since it ensures the compatibility of data within a program. In JavaScript, values are converted from one data type to another with the help of coercion and casting.

What is Coercion?

Coercion is a mechanism that implicitly converts types when performing certain operations. In order for an operation with two operands of different type to make sense, JavaScript converts one of the two.

Coercion can yeld unexpected results.
(click on the image to open in a new tab)

Here The typeof operator is used to determine the data type of value. In this example, the empty string “” is of type String. The unary plus operator + is used before the typeof expression. It converts the result of typeof “” into a Number. But since in our example, the string “” cannot be directly converted into a Number, the unary plus operator coerces it to NaN (Not-a-Number).

The concatenation operator + is used to combine the string “I am a “ with the coerced value NaN. The final result is the string “I am a number” because the NaN value, which is a Number, is implicitly converted (coerced) into a String during the concatenation process in order for the concatenation to make sense.

In JavaScript, data types, both primitives and objects, can be coerced into only three types: Numbers, Strings and Booleans.

Let’s see each of them in action.

String coercion

String coercion is triggered by the binary plus operator. The binary plus operator results in string concatenation in all cases except for when we have both operands as numbers. In that case is always a numeric addition.

The binary plus operator results in string concatenation in all cases except for when we have both operands as numbers.
(click on the image to open in a new tab)

We must take into account string concatenation when we receive data from input forms and want to implement mathematic addition.

Boolean coercion

Boolean coercion can lead to only two possible results. True or False.

We call the value types that when converting to booleans result in False, falsy, and all the other values, that respectively result in True, truthy.

There is a pretty short list of values that when converted to a boolean became False.

They are:

The above when converted to a boolean became False.
(click on the image to open in a new tab)

Implicit Boolean conversion can occur when non-boolean values are evaluated in a boolean context. That would be a conditional statement or an evaluation with logical operators.

Here some examples of converting values to Booleans.

The first if statement evaluates to true since a String is truthy. The second if statement evaluates to false because 0 is falsy.
(click on the image to open in a new tab)

In the example above, the first if statement evaluates to true since a String is not falsy, thus truthy, and the corresponding message is logged.

The second if statement evaluates to false because 0 is falsy, so the message is not logged.

In a logical operation the values are internally coerced to boolean so that the logical operation makes sense.
(click on the image to open in a new tab)

In this second example, we have an expression with logical operators.

In JavaScript, contrary to other C family languages, logical operators return the original operands and not the boolean values. But the values are internally coerced to boolean so that the logical operation makes sense.

An expression with more than one logical operator evaluates to the value of the last evaluated operand. The && and || operands are evaluated left to right.

The AND operator has a higher precedence over the OR operator, meaning the && operator is executed before the || operator.
(click on the image to open in a new tab)

Regarding the logical AND and logical OR evaluations in the example. The AND operator has a higher precedence over the OR operator, meaning the && operator is executed before the || operator. It evaluates to true so {} is returned. The logical OR (||) operator for a set of operands is true if and only if one or more of its operands are true. That is the case in the last evaluation, so the truthy value {} is returned.

Numeric coercion

Numeric coercion is triggered by most operators.

Bitwise operators:

Bitwise operators in JavaScript work directly with the binary versions of numbers.

They work on 32-bit integers, converting operands to binary, performing the operation bit by bit, and returning the result as a decimal number.

Here’s an example of the XOR JavaScript bitwise operator:

5 ^ 3 → 6 (binary: 0101 ^ 0011 = 0110).
(click on the image to open in a new tab)

Comparison operators:

Booleans often result from comparison operators and are combined using logical operators to form complex conditions:

Booleans often result from comparison operators.
(click on the image to open in a new tab)

Arithmetic operators:

Arithmetic operators will trigger a numeric conversion except for the plus operator which will not trigger a numeric conversion if any of the two operands is a String.

Arithmetic operators will trigger a numeric conversion except for the plus operator.
(click on the image to open in a new tab)

Loose equality operator

Loose equality, or double equals, operator will trigger numeric conversion before comparing the operands. But this rule will not apply when both of the operands are String s.

Double equals, operator will trigger numeric conversion before comparing the operands.
(click on the image to open in a new tab)

In line 10, true is coerced to NaN and true to 1, so we have NaN == 1 which evaluates to false. Next, false is coerced to 0 and false to NaN, so we have 0 == NaN which is false.

Regarding the expression in the last line, this is the exception. No numeric conversion is triggered. If both strings were coerced to numbers, we would have NaN == NaN, which is false, but here we get true.

Remember that loose equality won’t trigger numeric conversion when is applied to null or undefined, since both null and undefined equal only to null or undefined and nothing else.

What is Casting?

Sometimes we want to be explicit and tell the language, ‘I want you to convert the value type regardless of it making sense or not’.

It is an explicit programming decision we make, and in this case the type conversion mechanism is called casting.

Lets examine our previous example again.

Here we explicitly convert a String to a Number with the use of the unary operator.
(click on the image to open in a new tab)

We see that with the use of the unary operator we convert the String after the typeof operator to a Number. The code could make sense as is, without the use of the plus operator:

Without the unary operator the empty string remains a String.
(click on the image to open in a new tab)

But we want to explicitly convert it to a Number, thus the use of the unary operator. This is an example of casting.

In a nutshell, type casting is the manual conversion of one data type to another using explicit functions or operators.

All types of conversion can be achieved with type casting.

Explicit Numeric Conversion

Number constructor

When the Number constructor is called as a function Number (parameter), it coerces the parameter to a Number primitive. If coercion is not workable, it returns NaN.

The Number constructor, coerces a parameter to a Number primitive.
(click on the image to open in a new tab)

Using the Number() function is the only way to convert a BigInt to a Number.

The Number() function is the only way to convert a BigInt to a Number.
(click on the image to open in a new tab)

parseInt()

The parseInt() function is used to convert a value into an integer of a specified radix.

Syntax:

Syntax of the parseInt() function.
(click on the image to open in a new tab)

The radix shows the base in mathematical numeral systems.

This parameter is optional. If not provided, the default radix is 10, which is the base for the decimal numerical system.

The radix default value is 10.
(click on the image to open in a new tab)

The only exception to this rule is if the input string, with leading white-space and possible +/- signs removed, begins with a zero, followed by lowercase or uppercase X (0x or 0X). parseInt ignores any value after decimal.

Εxample:

parseInt ignores any value after decimal.
(click on the image to open in a new tab)

parseFloat()

By using the parseFloat() function, we can convert a String to a floating point number.

With parseFloat() function, we can convert a String to a floating point number.
(click on the image to open in a new tab)

Unary Operators

As we know from Math, unary operators are operators with only one operand. The unary operators that we can use to trigger numeric conversion are unary plus (+operand) and unary minus (- operand).

When we apply the unary plus operator to a non numeric value, it attempts to convert this value to a Number. If the operand cannot be converted to a Number, the result of the unary plus operation will be NaN. If the operand is already a Number, it remains unchanged.

When we apply the unary plus operator to a non numeric value, it attempts to convert this value to a Number.
(click on the image to open in a new tab)

The unary minus operator (- operand) can also trigger numeric conversion. It performs the same numeric conversion as the unary plus operator, but it additionally changes the sign of the resulting number.

The unary minus operator (- operand) can also trigger numeric conversion.
(click on the image to open in a new tab)

Unary operators, contrary to Number function, will throw a TypeError when encountering a BigInt.

Explicit Boolean Conversion

Explicit boolean conversion involves explicitly converting a value to a boolean using functions or operators.

Here are two common methods:

Boolean(parameter)

Boolean() function explicitly converts the numeric value 5 to the boolean value true.
(click on the image to open in a new tab)

In the example above, the Boolean() function explicitly converts the numeric value 5 to the boolean value true.

Double negation (!!) operator

The double negation casts to boolean. It is not an actual operator but two negation operators in a raw. The first ! negates once, then the other ! negates the value once more. This way if the parameter is truthy we get true as a result. If not, we get false.

The double negation casts to boolean.
(click on the image to open in a new tab)

In this example, the double negation operator !! is used to explicitly convert the strings “Hello” and “” to the boolean value true and false, respectively.

Explicit String Conversion

String Constructor

When the String() constructor is called as a function with a parameter, it converts the parameter value to a primitive string. The below examples show how you can use String() function to cast different types of values to String:

Converting objects

So far, we have looked at examples of type conversions regarding primitives. But in the last two examples, the data converted to a String was an Object.

We have mentioned that objects, just like primitives, can also be converted to a different data type. When objects are used in operations that expect primitive values, type coercion arises.

So when JavaScript encounters a reference type in a place where it expected a primitive, it doesn’t fail, but it uses an internal fallback mechanism that converts the reference type to a primitive. This mechanism is the build-in method [toPrimitive].

First, objects are converted into primitives and then they are converted again to one of the three types (String, Number, Boolean).

When JavaScript encounters a reference type in a place where it expected a primitive it converts it first to primitive, and then to one of the three types.
(click on the image to open in a new tab)

to numbers results in converting them to strings first. This will make the non-primitive become primitive, i.e. String. Then this primitive String is further coerced to a Number if an operand dictates so.

Example of Coercing non-primitives.
(click on the image to open in a new tab)

Below we see the steps JavaScript follows to the final coercion.

Each value in the expression is first coerced into a String.
(click on the image to open in a new tab)

In the example, each value in the expression is first coerced into a String, then the coercion progress further.

Another more simple example below:

Javascript converts the array into a String and then a Number.
(click on the image to open in a new tab)

And therefore it logs true:

[1] is coerced into a String, then to a Number, and then the evaluation takes place.
(click on the image to open in a new tab)

Regarding Equality

The loose equality operator, as we’ve seen so far, is the equality operator that allows type coercion. There is also a second equality operator, the triple equals or strict equality operator (===), that doesn’t allow coercion to take place.

Strict equality operators, contrary to loose equality operators, does not allow type coercion to take place.
(click on the image to open in a new tab)

We use the latter operator when we don’t want JavaScript to implicitly convert from one type to another. Note that type conversion can be achieved with the strict equality operator, but only explicitly.

Which one to use, type casting or coercion?

Most favor type casting for being more readable and more predictable.

Coercion can produce surprising results that make some programmers talk about coercion as being evil. Of course, coercion is not evil, nor does it have to be surprising. Completely avoiding implicit coercion is not recommended.

Coercion can be a powerful tool when used consciously and appropriately. And the element of surprise actually comes from a lack of understanding of how coercion works. There are cases where coercion can improve the readability of our code.

We can illustrate this with an example:

Here, developer2 experience is undefined, but this is not a problem with loose equality.
(click on the image to open in a new tab)

Here, since double equals permits coercion, the developer2.experience property which is undefined is coerced to null, so the condition is met. Should we use the triple equals operator, which does not permit coercion, we would be much more verbose.

Without coercion, we should be much more verbose.
(click on the image to open in a new tab)

So although most times we should favor type casting, this is not a rule written in stone. Understanding both implicit and explicit conversion is crucial to handle different scenarios and make informed programming decisions.

Although my blog doesn’t support comments, feel free to reply via email or X.