Type Coercion in JavaScript
Learn via video course
Type Coercion in JavaScript
Overview
Type coercion is one of the most asked interview questions on JavaScript, which is purely concept-based. To solve the type coercion problems, one must understand the rules and methods of type coercion in JavaScript. There are many data types like string, number, boolean, etc, So it is very important to know how these data types are coerced from one data type to another. Please read this article till the very end for a better understanding of this concept.
Scope
- In this article, Type coercion in JavaScript is explained with the help of various examples.
- Note: The internal type conversion functions and coercion algorithms are not discussed here.
What is Type Coercion in JavaScript?
Before understanding type coercion in JavaScript, refer to the example given below,
What do you think the result of the above variable 'total' will be? 0 (zero)? Yes, you are right. Even though the val_1 is of string data type and val_2 is of number data type, we get the result as zero because JavaScript has converted val_1 from string to a number before the subtraction, this is type coercion in JavaScript. Now observe the below example where we are adding both variables instead of subtracting them.
So now, What do you think the result of the above variable total will be? 20 (twenty)? Unfortunately, a Big No. Here you will get an unpredictable result which is 1010 i.e, a string. But why? This is also because of the type coercion in JavaScript. So without further ado, let us dive deep into type coercion in JavaScript and understand how it works.
As you have seen in the above examples, the process of converting values from one data type to another data type, like the conversion of a number data type into a string data type, is called Type Coercion in JavaScript. Type coercion can be seen when various arithmetic and comparison operations are performed on different data types in JavaScript. There are two types of Type Coercion in JavaScript: Implicit and explicit.
Implicit VS Explicit Coercion in JavaScript
Implicit type coercion: The synonym of the word 'implicit' is 'indirect'. Hence, as the word suggests, Implicit type coercion in JavaScript refers to the conversion of values from one data type to another data type without the interference of the developer or the type coercion that happened indirectly. In simple words, we can say that the implicit type coercion is performed automatically by javascript itself.
Examples
In the above example, you can see that myVar returns 1010 as a string instead of the addition value20. This is because of the implicit type coercion in JavaScript in which the number data type 10 is converted to a string data type implicitly and then due to the string concatenation, 1010(a string) is returned instead of 20(a number).
Explicit type coercion: The synonym of the word 'explicit' is 'direct'. Hence, as the word suggests, Explicit type coercion in JavaScript refers to the conversion of values from one data type to another data type with the interference of the developer or the type coercion that happened directly. In simple words, we can say that the Explicit type coercion is performed by the developer himself and does not happen automatically.
Examples
In the above example, you can see that myVar returns 10 as a string. This is because of the explicit type coercion in JavaScript in which the number data type 10 is converted to a string data type explicitly.
Types of Conversion in JavaScript
There are three types of conversion in JavaScript that can be used to convert values from one data type to another data type by implicit as well as explicit type coercion. The behavior of JavaScript during type coercion is different for primitives and objects. Hence, first we will see for primitives, and later on, we will see it for objects in JavaScript.
To string
Implicit type coercion: If any string data type value is concatenated (using the + arithmetic operator) to 'another' data type, that 'another' data type is converted into string implicitly. Examples:
Explanation
- In myVar_1, myVar_2, and myVar_3 above, the number data type is converted into string data type implicitly due to concatenation with string.
- Similarly, in myVar_4, a boolean data type is converted to a string data type implicitly due to concatenation with string.
Explicit type coercion: We can use the String() function, which is provided by JavaScript, to convert any other data type into the string data type.
Examples
Explanation:
- In the variable myVar_1 , a positive number is converted to a String value. Hence, 45 is returned as a String.
- In the variable myVar_2 , a negative number is converted to a String value. Hence, -45.22 is returned as a String.
- In the variable myVar_3 and myVar_4 , boolean values are converted to String values. Hence, true and false are returned as a String.
- In the variable myVar_5 , null is converted to a String value. Hence, null is returned as a String.
- In the variable myVar_6 , undefined is converted to a String value. Hence, undefined is returned as a String.
To boolean
Implicit type coercion: When logical context appears or logical operations are performed by logical operators, type coercion to boolean data type happens implicitly.
Example
In the above example, due to the logical context, I am true is returned in the console due to the implicit type coercion to the boolean data type.
Explicit type coercion: We can use the Boolean() function which is provided by JavaScript to convert any other data type into the boolean data type.
Examples
In the above given examples, you can notice that when we convert 0, '' (an empty string), NaN, false, undefined and null, false is returned in the console. For every empty value like an empty array, object, etc. true is returned except an empty string. Refer to the example given below.
To number
Implicit type coercion: While dealing with other data types with numbers using comparison operators, arithmetic operators, bitwise operators, and not strict equality operator(==), other data types are converted to number implicitly.
Examples
- In the variable a1, 10 is returned as a number due to implicit type coercion.
- In the variable a2, true is converted to 1 as a number implicitly; hence 1 is returned.
- In the variable a3, string data type 5 is converted to number data type 5 before the equality comparison implicitly due to not strict equality operator(==), hence false is returned as 5 is not equal to 10.
- In the variable a4, string data type 6 is converted to number data type 6 implicitly before the comparison of values, hence true is returned as 4 less than 6 in value.
- In the variable a5, we saw an exceptional case where a number 10 gives 1010 as a string when added with the string 10 while we expected 20 as a result. Actually, concatenation has happened here instead of addition because JavaScript gives priority to concatenation over addition when + operator is used between a numeric string and a number.
Explicit type coercion: We can use the Number() function, which is provided by JavaScript, to convert any other data type into the number data type.
Examples
- In the variable a1, string data type 10 is converted to a number data type 10 explicitly using the Number() function.
- In the variable a2, boolean data type false is converted to a number data type 0 (zero) explicitly using the Number() function.
- In the variable a3, boolean data type true is converted to a number data type 1 (one) explicitly using the Number() function.
String to Number Conversion
As we have discussed above, any primitive data type can be converted to the number data type using the Number() function provided by JavaScript. Hence to convert string to the number data type, we can use the Number() function. Note that the Number() function only converts the numeric strings and not the alphabetic strings. Let us see some more examples-
In the above examples, you can notice that the variable myNum1 returned 15 as a number because 15 was a numeric string while the variable myVar2 returned NaN (Not a Number) because hello is not a numeric string.
Boolean to Number Conversion
As we have discussed above, any primitive data type can be converted to the number data type using the Number() function provided by JavaScript. Hence to convert a boolean to the number data type we can use the Number() function. Note that the Number() function converts the boolean true to 1 and the boolean false to 0. Let us see some more examples-
In the above examples, you can notice that the variable myNum1 returned 1 as a number as true is converted to 1 whereas myNum2 returned 0 as a number as false is converted to 0.
The Equality Operator (==)
The equality or not strict equality operator also leads to type coercion implicitly. But why? because the Equality operator (==) converts the other data type operands to the common or same data type operands and then compares the equality of both the operands. Let us see some examples-
- In val_1 and val_2, numeric String is converted to number data type just before the equality comparison, hence it returns true for val_1 and false for val_2.
- In val_3 and val_4, true is converted to 1 and false is converted to 0 just before the equality comparison, hence true is returned in both cases.
One more thing: In the below example, we have assigned 3 as a value to variable num. When we used strict equal operator(===) to check if 3 equals to true or not, we got false but at the same time when we used num inside the if's conditon block we get it as true as the code inside the if block runs successfully. But Why?
It is because the strict equal operator (===) checks the equality without converting the operands to the same or common data type. Hence in the first console.log we got false as num is of number data type while true is of boolean data type. But when we used num inside the if's condition block it returns true as we have discussed earlier that every number gets converted to true except zero during the implicit type coercion to boolean data type. Hence in the second console.log present in the if condition's body, we get 'test' printed in the console.
Rules for Type Coercion in JavaScript
In Type coercion, there are two special rules that you should always remember -
- As we have seen equality operator(==) above, we noticed that it converts both the operands to the common data type and then performs the equality comparison, but in the case of null and undefined, numeric conversion does not happen at all, which means that these values are not converted before the equality comparison. Refer to the examples given below.
If you notice the above-given examples, you can see that in the variable typeVal_1, null is not converted to zero before conversion; hence it returns false, and the variable typeVal_2 returns true as null equals undefined only and nothing else.
- The NaN in JavaScript never returns true when compared with other values using the equality operator. Surprisingly, it does not returns true even when compared with itself. Refer to the examples given below-
In the above examples, you can see that NaN returns false when compared with other operands and even itself using the equality operator(==) .
Type Coercion for Objects
As we have seen type coercion for primitives above, now we will look into the type coercion for objects in JavaScript. Here also we will see three conversion types that are to string, to boolean and to number. For the object type coercion, firstly the object value is converted to the primitive value and then proceeds further for type coercion. Let us see them one by one.
Even for objects also, the most simple and easy to understand type coercion is of boolean. All the non primitive values like objects or arrays are converted to true. It does not matter whether they are empty or filled with values, they are always coerced or converted to true.
First of all, Objects are converted to primitives by one of the internal methods in JavaScript that is [[ToPrimitive]]. Let us see the pseudo implementation of [[ToPrimitive]] method-
The [[ToPrimitive]] method accepts two arguments: an input value and a preferred type of conversion: Number or String where the preferredType can be passed or can be avoided too as its an optional argument. The input object has two methods: valueOf() adn toString(), which are used for numeric as well as string conversion. Both of these objects are available for any derived type like Array, Date, etc as they are declared on Object.prototype.
The conversion algorithm or steps of type coercion for objects are -
- If the given input is a primitive value, return it as it is.
- If the given input is not a primitive value then call the input.toString() method and if the result becomes primitive then return the result.
- If the given input is still not a primitive value then call the input.valueOf() method and if the result becomes primitive then return the result.
- In case if both of the methods do not convert the object to the primitive then just return a TypeError.
During numeric conversion, the valueOf() method is called first and the toString() method is called later if needed, while during the String conversion, firstly the call is made to the toString() method and then the valueOf() method is called if needed. As most of the built-in types in JavaScript do not have the valueOf() method, during the numeric as well as the string conversion, only the toString() method might get called.
Example
In the above example, we can see that the addition of the variable num and object myContainer is returned as 20, which is correct. It is because of the valueOf() method in the object 'myContainer' which returned 8. In case the value of the method is not present in the object, NaN is returned.
ES6 Symbol.toPrimitive Method
The latest type coercion feature in JavaScript is the symbol Symbol.toPrimitive, it is an ES6 feature that can be used as an object method. The specialty of this method is that it gives a common interface for converting an object into a primitive. Symbol.toPrimitive method can override the toString() method and the valueOf() method. This simply means that the Symbol.toPrimitive method will be taken into consideration even if both of the other methods are also present. When Symbol.toPrimitive method runs, it accepts a single hint argument that can have any of these values: number, string, or default as per the situation.
The Symbol.toPrimitive method overrides both the toString() and the valueOf() methods even when both are present or provided:
Conclusion
- We have seen what type coercion is in JavaScript and its examples.
- We have seen different types of type coercion.
- We got to know about implicit and explicit type coercion.
- We have seen type coercion for primitives.
- We have seen type coercion for objects as well.
- We have seen the different behavior of JavaScript during type coercion of primitives and objects.
- We have seen how the equality operator can also result in type coercion.
- Type coercion is also asked in JavaScript-specific interviews.
- We got to know that type coercion can have a negative impact on your program; hence it should be avoided.