-
Type Coercion
- What is Type Coercion?
- Different Types of Type Coercion?
- Implicit Type Conversion/Coercion Based on Operator
- Addition Operator (+) Implicit Type Conversion/Coercion
- Subtraction Operator (-) Implicit Type Conversion / Coercion
- Division Operator (/) Implicit Type Conversion / Coercion
- Multiplication Operator (*) Implicit Type Conversion/ Coercion
- Greater Than Operator (>) Implicit Type Conversion / Coercion
- Loose Equality Operator (==) Implicit Type Conversion / Coercion
- Strict Equality Operator (===) Implicit Type Conversion / Coercion
- Logical And (&&), Logical OR(||) and Logical NOT (!) Operator Type Conversion / Coercion
- Implicit Type Conversion / Coercion for Null, Undefined and NaN
- Explicit Type Coercion
- Explicit String Conversion / Coercion
- Explicit Boolean Conversion / Coercion
- Explicit Number Conversion / Coercion
- References
Type Coercion
What is Type Coercion?
The terms type coercion, type conversion, type casting, and type juggling all refer to the process of converting one data type to another. This process is extremely important in computer science and can be found in almost every programming language.
Different Types of Type Coercion?
There are two types of coercion
available in JavaScript. They are implicit type coercion
and explicit type coercion
.
Implicit Type Coercion is not intentional. This type of coercion is done by Javascript itself. The Developer has no control over implicit type coercion. Most of the unexpected behavior (80%) happens in JavaScript by implicit type coercion
. Some examples are:
console.log(2 * "5") // 10
console.log("12" - "10") // 2
console.log(true + true) // 2
console.log(10 * [6]) // 60
Explicit Type Coercion is intentional and done by the developers. Developers have full control over explicit type coercion. The code behavior of explicit type coercion
is obvious and expected. Some examples are:
// Number to String
console.log(String(123)); // "123"
// Number to Boolean
console.log(Boolean(2)); // true
// String to Number
console.log(Number("123")); // 123
Whether it is implicit or explicit type coercion, JavaScript can only convert/coerces
to the string
, number
, and Boolean
primitive types. There’s no way in JavaScript to coerce
a value type to an object
or function
.
Implicit Type Conversion/Coercion Based on Operator
Addition Operator (+) Implicit Type Conversion/Coercion
In JavaScript, the "+" symbol is used for addition. The "+" operator performs calculations from left to right. Here are some examples of implicit type coercion using the addition operator, along with their explanations.
Note:
You will see comments like the following. Here nested comments are same-line comments. I wrote nested comments for enhancing readability.
// "+" operator work left to right so that
// first it add two number and then convert
// them to string
// ==> 18 + "number"
// ==> "18number"
// "+" operator work left to right so that first it add two number and then convert them to string
// ==> 18 + "number"
// ==> "18number"
console.log(true + false); // 1
// true coerces to 1 and false coerces to 0
// ==> 1 + 0
// ==> 1
console.log(true + true); // 2
// true coerces to 1 and false coerces to 0
// ==> 1 + 1
// ==> 2
console.log(false + false); // 0
// true coerces to 1 and false coerces to 0
// ==> 0 + 0
// ==> 2
console.log("1" + 1); // "11"
// "+" operator work left to right
// ==> "1" + 1
// ==> "11"
console.log("4" + true); // "4true"
// Exception: Symbol cannot convert to string
console.log("" + Symbol("my symbol"));
// TypeError: Cannot convert a Symbol value to a string
console.log("number" + 15 + 3); // "number153"
// "+" operator work left to right
// ==> "number15" + 3
// ==> "number153"
console.log(15 + 3 + "number"); // "18number"
// "+" operator work left to right so that
// first it add two number and then convert
// them to string
// ==> 18 + "number"
// ==> "18number"
console.log("foo" + +"bar"); // "fooNaN"
// Here (+"bar"), "+" operator act like
// unary plus operator, which tries to
// convert its operand into a number.
// Since the operand is the string "bar",
// which cannot be directly converted into a number,
// it results in NaN
// ==> "foo" + (+"bar")
// ==> "foo" + NaN
// ==> "fooNaN"
console.log({} + {}); // "[object Object][object Object]"
// curly brace {} represent empty object
// and converted to "[object Object]"
// ==> "[object Object]" + "[object Object]"
// ==> "[object Object] [object Object]"
console.log({} + []); // "[object Object]"
// curly brace {} represent empty object
// and converted to "[object Object]" and
// empty array [] converted to empty string ""
// ==> "[object Object]" + ""
// ==> "[object Object]"
console.log([] + []); // ""
// empty array [] converted to empty string ""
// ==> "" + ""
// ==> ""
console.log([1] + []); // "1"
// when you use the "+" operator with arrays,
// it performs array-to-string conversion
// ==> "1" + ""
// ==> "1"
console.log([1, 2] + []); // "1,2"
// when you use the "+" operator with arrays,
// it performs array-to-string conversion
// ==> "1,2" + ""
// ==> "1,2"
console.log(!([1] + [])); // false
// If logical operator (&&, ||, !) used in
// implicit coercion, then it will give
// output in boolean
// !("1") : "1" is truthy value so !("1") = false
// ==> !("1" + "")
// ==> !("1")
// ==> false
console.log({} + [] + {} + [1]); // "[object Object][object Object]1"
// ==> "[object Object]" + "" + "[object Object]" + "1"
// ==> "[object Object][object Object]1"
console.log(!+[] + [] + ![]); // "truefalse"
// +[]: The + operator is used here as the
// unary plus operator, which tries to convert
// its operand into a number. The operand []
// represents an empty array, which is coerced
// into the number 0. So +[] evaluates to 0.
// !0: As 0 is a falsy value so !0 will be true
// ![]: An empty array is considered a truthy value,
// so ![] evaluates to false.
// ==> (!+[]) + [] + (![])
// ==> !0 + [] + false
// ==> true + [] + false
// ==> true + "" + false
// ==> "truefalse"
Subtraction Operator (-) Implicit Type Conversion / Coercion
The -
symbol is the subtraction operator in JavaScript. When applied to a string and a number, JavaScript automatically tries to convert the string to a number before performing the subtraction.
console.log("10" - 10); // 0
// ==> 10 - 10
// ==> 0
console.log(10 - "10"); // 0
// ==> 10 - 10
// ==> 0
console.log("2" - 1); // 1
// ==> 2 - 1
// ==> 1
Division Operator (/) Implicit Type Conversion / Coercion
The /
symbol is the division operator in JavaScript. When applied to a string and a number, JavaScript automatically tries to convert the string to a number before performing the division.
console.log(12 / 6); // 2
// ==> 2
console.log(12 / "6"); // 2
// ==> 12 / 6
// ==> 2
console.log("12" / "6"); // 2
// ==> 12 / 6
// ==> 2
Multiplication Operator (*) Implicit Type Conversion/ Coercion
The *
symbol is the multiplication operator in JavaScript. When applied to a number and a string, JavaScript automatically tries to convert the string to a number before performing the multiplication.
console.log(12 * 6); // 72
// ==> 72
console.log(12 * "6"); // 72
// ==> 12 * 6
// ==> 72
console.log("12" * "6"); // 72
// ==> 12 * 6
// ==> 72
Greater Than Operator (>) Implicit Type Conversion / Coercion
In JavaScript, when comparing values using the Greater Than >
operator, both operands are automatically converted to numbers before the comparison is made.
console.log(6 > "5"); // true
// ==> 6 > 5
// ==> true
console.log("6" > "45"); // true
// When comparing characters, JavaScript compares
// their leftmost Unicode values (UTF-16).
// The first character of "6" is "6",
// and the first character of "45" is "4".
// The Unicode value of "6" is 54 and "4" is 52.
// So "6" is greater than "4".
// Thats why it evaluates to true
// Unicode table: https://asecuritysite.com/coding/asc2
// ==> "6" > "4"
// ==> 54 > 52
// ==> true
console.log("6" > "75"); // false
// When comparing characters, JavaScript compares
// their leftmost Unicode values (UTF-16).
// The first character of "6" is "6",
// and the first character of "75" is "7".
// The Unicode value of "6" is 54 and "7" is 55.
// So "7" is greater than "6"
// Thats why it evaluates to flase
// Unicode table: https://asecuritysite.com/coding/asc2
// ==> "6" > "7"
// ==> 54 > 55
// ==> flase
Loose Equality Operator (==) Implicit Type Conversion / Coercion
Loose equality operator (==) operator performs type coercion before making the comparison. After the type coercion, the loose equality operator (==) checks only the equality of values and ignores the original types.
console.log("true" == true); // false
// "true" trying to convert it into number.
// But as it is not a number so it returns NaN
// true convert it into number 1
// ==> "true" == true
// ==> NaN == 1
// ==> false
console.log(false == "false"); // false
// ==> 0 == NaN
// ==> false
console.log(!!"false" == !!"true"); // true
// ==> !!NaN == !!NaN
// ==> !true == !true
// ==> false == false
// ==> true
console.log(["x"] == "x"); // true
// ==> "x" == "x"
// ==> true
console.log(10 == "10"); // true
// Here string type coerces into number befor comparison.
// Now both values are same. So that it retun true
// ==> 10 == 10
// true
console.log([10] == 10); // true
// First, Array coerces to string
// Then string type coerces into number before comparison.
// Now both values are same. So that it retun true
// ==> "10" == 10
// ==> 10 == 10
// ==> true
console.log([10] == "10"); // true
// First, Array converted to string
// Now both values are same. So that it retun true
// ==> "10" == "10"
// ==> true
Strict Equality Operator (===) Implicit Type Conversion / Coercion
The Strict equality operator (===) operator does not perform type coercion. It performs strict equality comparison so checking both value and type.
console.log(10 === "10"); // false
// The number 10 is a numeric value,
// while the string "10" is a string value.
// As type doesn't match thats why they return false
console.log([10] === 10); // false
// The array [10] is an object type,
// while the number 10 is a number type.
// As type doesn't match thats why they return false
console.log([10] === "10"); // false
// The array [10] is an object type,
// while the string 10 is a string type.
// As type doesn't match thats why they return false
Logical And (&&), Logical OR(||) and Logical NOT (!) Operator Type Conversion / Coercion
When evaluating a logical AND operation, JavaScript follows these rules:
- If the first operand is truthy (not equal to false, null, undefined, 0, NaN, or an empty string), the second operand is returned.
- If the first operand is falsy, it is returned without evaluating the second operand.
When evaluating a logical OR operation, JavaScript follows these rules:
- If the first operand is
truthy
, it is returned without evaluating the second operand. - If the first operand is falsy (equal to false, null, undefined, 0, NaN, or an empty string), the second operand is returned.
// logical operator internally convert to Boolean
// but it returns in original value
// the following expression will returns
// number 123, instead of returning true
// 'hello' and 123 are still coerced to boolean
// internally to calculate the expression
console.log('hello' && 123); // 123
// In this case, "hello" is a non-empty string,
// which is a `truthy` value in JavaScript.
// Therefore, the logical AND operation continues
// to evaluate the second operand, 123.
console.log("hello" || 123); // "hello"
// In this case, "hello" is a non-empty string,
// which is a `truthy` value in JavaScript.
// Therefore, the logical OR operation returns
//the truthy value of the first operand,
// which is "hello"
console.log(![]); // false
// ![] : [] is truthy value so ![] = false
console.log([] == ![]); // true
// The loose equality operator (==) operator
// in JavaScript performs type coercion
// before making the comparison.
// ==> "" == false
// ==> 0 == 0
// true
console.log([] === ![]); // false
// Strict equality operator does not perform
// type coercion and check type & value
// ==> [] == false
// ==> false
console.log(!4); // false
console.log(!!4); // true
Implicit Type Conversion / Coercion for Null, Undefined and NaN
- Null implicit type coercion :
console.log(null + null); // 0
// null coerces to O.
// ==> 0 + 0
// ==> 0
console.log(null + 3); // 3
// null coerces to O.
// ==> 0 + 3
// ==> 3
console.log(null - 3); // -3
// null coerces to O.
// ==> 0 -3
// ==> -3
console.log("4" + null); // "4null"
console.log([] + null + 1); // "null1"
// ==> "" + null + 1
// ==> "null" + 1
// ==> "null1"
console.log(null > 0); // false
// ==> 0 > 0
// ==> false
console.log(null < 3); // 3
// ==> 0 < 3
// ==> true
console.log(null + ""); // "null"
// ==> null + ""
// ==> "null"
console.log(null + "3"); // null3
// ==> null + "3"
// ==> "null3"
console.log(null == null); // true
// If you compare null with null
// or undefined you will get true.
// Rest of the case it will return false.
console.log(null === null); // true
console.log(null == ""); // false
console.log(null == 5); // false
console.log(null === 5); // false
console.log(null == true); // false
console.log(null == false); // false
console.log(null == NaN); // false
- Undefined implicit type coercion :
console.log(undefined + undefined); // NaN
// undefined coerces to NaN
// ==> NaN + 0
// ==> NaN
console.log(undefined + 3); // NaN
// ==> NaN + 3
// ==> NaN
console.log(undefined - 3); // NaN
// ==> NaN -3
// ==> NaN
console.log("4" + undefined); // "4undefined"
// ==> "4" + undefined
// ==> "4undefined"
console.log(undefined > 4); // false
// When comparing undefined with any
// value using a relational operator like >,
// JavaScript treats undefined as NaN (Not-a-Number).
// ==> NaN > 4
// false
console.log(undefined == ""); // false
// If you compare undefined with null
// or undefined you will get true.
// Rest of the case it will return false.
console.log(undefined == true); // false
console.log(undefined == false); // false
console.log(undefined == undefined); // true
console.log(undefined === undefined); // true
console.log(undefined == NaN); // false
- Null and Undefined type coercion together
console.log(null + undefined); // NaN
// null and undefined are not numeric values.
// In this case, JavaScript tries to convert them
// into numbers
// null is coerced into a number, it becomes 0
// undefined is coerced into a number,
// it becomes NaN (Not-a-Number)
// When we add 0 with NaN, the result is NaN.
// ==> 0 + NaN
// ==> NaN
console.log(null - undefined); // NaN
// null and undefined are not numeric values.
// In this case, JavaScript tries to convert
// them into numbers
// null is coerced into a number, it becomes 0
// undefined is coerced into a number,
// it becomes NaN (Not-a-Number)
// When we subtract 0 with NaN,
// the result is NaN.
// ==> 0 - NaN
// ==> NaN
console.log(null == undefined); // true
// If you compare null/undefined with null or
//undefined you will get true.
// Rest of the case it will return false.
console.log(null === undefined); // false
// null is an object type,
// while undefined is a undefined type.
// As type doesn't match thats why they return false
- NaN implicit type coercion
console.log(NaN + NaN); // NaN
// ==> NaN + NaN
// ==> NaN
console.log(NaN + 3); // NaN
// ==> NaN + 3
// ==> NaN
console.log(NaN - 3); // NaN
// ==> NaN - 3
// ==> NaN
console.log("4" + NaN); // "4NaN"
// ==> "4" + NaN
// ==> "4NaN"
console.log([] + NaN + 1); // "NaN1"
// ==> "" + NaN + 1
// ==> "NaN" + 1
// ==> "NaN1"
console.log(NaN > 0); // false
// Any comparison involving NaN evaluates to false.
// NaN is not a valid number,
// and thus cannot be compared to
// any other value, even to itself.
console.log(NaN < 3); // false
console.log(NaN + ""); // "NaN"
// ==> NaN + ""
// ==> "NaN"
console.log(NaN + "3"); // "NaN3"
// ==> NaN + "3"
// ==> "NaN3"
console.log(NaN == NaN); // false
console.log(NaN === NaN); // false
console.log(NaN == ""); // false
console.log(NaN == true); // false
console.log(NaN == false); // false
console.log(null == NaN); // false
Explicit Type Coercion
We know that, Whether it is implicit or explicit type coercion, JavaScript can only convert/coerces
to the string
, number
, and Boolean
primitive types. There’s no way in JavaScript to coerce/convert
a value type to an object
or function
.
Explicit String Conversion / Coercion
Explicitly we can convert anything to a string with JavaScript String()
method.
console.log(String(43)); // "43"
console.log(String(-43.3)); // "43.3"
console.log(String(null)); // "null"
console.log(String(undefined)); // "undefined"
console.log(String(NaN)); // NaN
console.log(String(true)); // "true"
console.log(String(false)); // "false"
console.log(String(Symbol("my symbol"))); // "Symbol(my symbol)"
Explicit Boolean Conversion / Coercion
Explicitly we can convert anything to a boolean with JavaScript Boolean()
method.
We know that a boolean only return true
or false
. Boolean that only returns falsy
values is the following:
console.log(Boolean("")); // false
console.log(Boolean(0)); // false
console.log(Boolean(-0)); // false
console.log(Boolean(NaN)); // false
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(false)); // false
Anything except the above list will return true
. The following list will return true
.
console.log(Boolean({})); // true
console.log(Boolean([])); // true
console.log(Boolean(Symbol())); // true
console.log(!!Symbol()); // true
console.log(Boolean(function () {})); // true
Explicit Number Conversion / Coercion
Explicitly we can convert anything to a Number or NaN (not-a-number) with JavaScript Number()
method.
console.log(Number(123)); // 123
console.log(Number(" 12s ")); // NaN
console.log(Number(" 12 ")); // 12
console.log(Number("-12.34")); // -12.34
console.log(Number(null)); // 0
console.log(Number(undefined)); // NaN
console.log(NaN); // NaN
console.log(Number(true)); // 1
console.log(Number(false)); // 0
console.log(Number("\\n")); // NaN
References
- Type Coercion in JavaScript
- JavaScript type coercion explained
- JavaScript Type Conversions
- JavaScript - Type Coercion Explained
- Javascript Tricky Questions — Type Coercion
Thanks for reading ✨!
Connect with me on LinkedIn
Don't forget to share your thoughts in the comment section.
Top comments (0)