Type Coercion in JavaScript

javascript
Type Coercion text and some JS code around it

What is Type Coercion

Type coercion (or typecasting) is a language's ability to automatically convert data types.

Let’s see the basics:

const num = 4;
    const str = '2';
    console.log(num + str);  //output: '42'

Here num is implicitly converted to a string and then concatenated with str .

When you use the + operator with a number and a string, JavaScript performs type coercion, which results 42 .

This behavior is an example of type coercion in JavaScript, where values are automatically converted from one data type to another when an operation expects a different type.

Types of Coercion

Type coercion can be categorized into two main types:

Implicit

  • Happens automatically during operations
  • Can sometimes lead to unexpected results
  • For example - when adding a string and a number, JavaScript implicitly coerces the number to a string

Some examples with Implicit Coercion:

let isTrue = "5" == 5; // isTrue is true (loose equality, coerces types)
    // The loose equality (==) operator performs implicit coercion..
    // so even though num is a number and str is a string, they are considered equal
let result = "5" + 3; // result is "53" (string concatenation)
let total = "10" - 5; // total is 5 (string "10" coerced to a number)
let age = 25;
    let message = "I am " + age + " years old.";
    console.log(message); // Outputs: "I am 25 years old."
    
    // The number age is implicitly coerced into a string when it is concatenated with the string
let x = 10;
    let y = "5";
    if (x > y) {
      console.log("x is greater than y.");
    } else {
      console.log("x is not greater than y.");
    }
    
    // Here the string y is implicitly coerced into a number during the comparison

Explicit

  • Occurs when you intentionally convert a value from one type to another
  • Done using built-in functions or by writing custom conversion logic
  • Provides more control over the conversion process

And some more examples with Explicit Coercion

let stringValue = Number("42"); // 42
    let nonNumericString = Number("Hello"); // NaN
    
    let undefinedValue = Number(undefined); // NaN
    let nullValue = Number(null); // 0
    let trueValue = Number(true); // 1
    let falseValue = Number(false); // 0
    let objectValue = Number({ key: "value" }); // NaN
    let symbolValue = Number(Symbol("mySymbol")); // Throws TypeError
    let functionValue = Number(function() { /* function body */ }); // NaN
let stringNumber = String(123); // "123"
    let undefinedValue = String(undefined); // undefined
    let nullValue = String(null); // null
    let booleanValue = String(true); // "true"
    let booleanValue = String(false); // "false"
    let stringValue = String("Yee claw!"); // "Yee claw!"
    let objectValue = String({ key: "value" }); // "[object Object]"
    let symbolValue = String(Symbol("mySymbol")); // "Symbol(mySymbol)"
    let functionValue = String(function() { /* function body */ }); // "function () { /* function body */ }"
let booleanValue = Boolean(7); // true
    
    // Rule of thumb for Boolean Conversion
    
    // When explicitly converting values to boolean using the Boolean() function or relying on the truthiness/falsiness of values in a boolean context (such as in an if statement), here's a general guide:
    
    // Falsy Values:
    // false (boolean false)
    //  0 (numeric zero)
    // "" (empty string)
    // null
    // undefined
    // NaN
    
    // Truthy Values:
    
    // true (boolean true)
    // Any non-zero number (positive or negative)
    // Non-empty strings
    // Objects (including arrays and functions)
let fruits = ["apple", "banana", "orange"];
    let fruitsString = fruits.toString();
    console.log(fruitsString); // Outputs: "apple,banana,orange"
let csvString = "apple,banana,orange";
    let fruitsArray = csvString.split(",");
    console.log(fruitsArray); // Outputs: ["apple", "banana", "orange"]
let numericString = "42";
    let integerValue = parseInt(numericString);
    console.log(integerValue + 8); // Outputs: 50
let floatString = "3.14";
    let floatValue = parseFloat(floatString);
    console.log(floatValue + 1); // Outputs: 4.14
let value = 42;
    console.log(typeof value); // Outputs: "number"
    
    value = "Hello";
    console.log(typeof value); // Outputs: "string"
    
    // The typeof operator implicitly coerces the variable into a string representation of its type.

Bonus:

I came across a post on javascript.info where someone was puzzled about why 4 + 5 + "px" results in "9px", while "$" + 4 + 5 gives "$45".

The explanation provided by another user (Pratik Singh) was spot-on:

The order of evaluation of an expression is from "left to right" incase the operators are of same priority. So in the above case it will be evaluated as shown below:

4 + 5 + "px" ==> (4+5) +"px" ==> 9 + "px" ==> 9px

ℹ️ Explanation: since both are addition i.e of same priority(BODMAS rule) therefore left one will be executed first and that results into 9 and then 9 + "px" will be evaluated which yields 9px.

"$" + 4 + 5 ==>"$45"

Explanation: since again both operations are addition so left one will be executed first which results into "$4" + 5 and then this is evaluated which then becomes "$45".