Ad – 728Γ—90
🌱 Beginner

JavaScript Type Conversion – Explicit and Implicit Coercion

JavaScript is a dynamically typed language that will silently convert values between types in many situations β€” sometimes helpfully, sometimes surprisingly. This automatic conversion is called implicit coercion. You can also convert types intentionally using functions like String(), Number(), and Boolean() β€” that's explicit conversion. Understanding both is essential for writing bug-free code and explaining the most common JavaScript interview questions.

⏱️ 23 min read 🎯 Beginner πŸ“… Updated 2026

Implicit Coercion – When JavaScript Decides

Implicit coercion happens automatically when JavaScript applies an operator to values of different types. The most famous cases involve the + operator:

JavaScript
// + with a string: everything becomes a string
console.log("5" + 3);       // "53"  β€” number coerced to string
console.log("5" + true);    // "5true"
console.log("5" + null);    // "5null"
console.log("5" + undefined); // "5undefined"

// - * / % trigger numeric coercion (they only do math)
console.log("5" - 3);       // 2    β€” string coerced to number
console.log("5" * "2");     // 10
console.log("6" / "2");     // 3
console.log("hello" - 1);   // NaN  β€” "hello" can't become a number

// Comparison operators also coerce
console.log("5" > 3);       // true β€” "5" becomes 5
console.log(null > 0);      // false
console.log(null == 0);     // false (null only == undefined)
console.log(null >= 0);     // true  β€” bizarre but true!
β–Ά Output
"53" "5true" "5null" "5undefined" 2 10 3 NaN true false false true
⚠️
The + Operator is Special

The + operator does double duty: addition for numbers, concatenation for strings. If either operand is a string, it concatenates. This is why "10" + 5 gives "105" but "10" - 5 gives 5. Always convert inputs explicitly before arithmetic.

Explicit Conversion

Explicit conversion means you intentionally convert a value using a built-in function. This is always preferred over relying on implicit coercion.

JavaScript
// String() β€” converts any value to string
console.log(String(42));          // "42"
console.log(String(true));        // "true"
console.log(String(null));        // "null"
console.log(String(undefined));   // "undefined"
console.log(String([1, 2, 3]));   // "1,2,3"

// Number() β€” converts to number (strict: invalid = NaN)
console.log(Number("42"));        // 42
console.log(Number("42.5"));      // 42.5
console.log(Number(""));          // 0
console.log(Number(true));        // 1
console.log(Number(false));       // 0
console.log(Number(null));        // 0
console.log(Number(undefined));   // NaN
console.log(Number("hello"));     // NaN

// parseInt / parseFloat β€” more lenient
console.log(parseInt("42px"));    // 42 (ignores trailing text)
console.log(parseFloat("3.14em")); // 3.14

// Boolean() β€” converts to boolean
console.log(Boolean(1));          // true
console.log(Boolean(0));          // false
console.log(Boolean("hello"));    // true
console.log(Boolean(""));         // false
console.log(Boolean(null));       // false
β–Ά Output
"42" "true" "null" "undefined" "1,2,3" 42 42.5 0 1 0 0 NaN NaN 42 3.14 true false true false false
Ad – 336Γ—280

Truthy and Falsy Values

In a boolean context (like an if condition), every value is either truthy or falsy. There are exactly 8 falsy values in JavaScript β€” everything else is truthy.

Falsy ValuesNotes
falseThe literal false
0Zero
-0Negative zero
0nBigInt zero
""Empty string
nullIntentional absence
undefinedUnassigned
NaNNot a Number
JavaScript
// All falsy β€” these if blocks do NOT run
if (false)     console.log("false");
if (0)         console.log("zero");
if ("")        console.log("empty string");
if (null)      console.log("null");
if (undefined) console.log("undefined");
if (NaN)       console.log("NaN");

// Truthy surprises β€” these DO run!
if ("0")       console.log('"0" is truthy!');  // non-empty string
if ("false")   console.log('"false" is truthy!');  // non-empty string
if ([])        console.log('[] is truthy!');   // empty array
if ({})        console.log('{} is truthy!');   // empty object
if (-1)        console.log('-1 is truthy!');   // any non-zero number
β–Ά Output
"0" is truthy! "false" is truthy! [] is truthy! {} is truthy! -1 is truthy!
πŸ’‘
Double-Bang !! Converts to Boolean

!! is a common idiom to explicitly convert any value to a boolean. !!null gives false, !!"hello" gives true. The first ! negates and coerces to boolean; the second ! negates back to get the correct boolean value.

The == vs === Coercion Table

Loose equality (==) applies type coercion using complex rules. Here are the most important cases to memorize:

JavaScript
// Surprising loose equality results
console.log(false == 0);        // true
console.log(false == "");       // true
console.log(false == "0");      // false (!)
console.log(0 == "");           // true
console.log(0 == "0");          // true
console.log("" == "0");         // false
console.log(null == undefined); // true
console.log(null == 0);         // false
console.log(undefined == 0);   // false
console.log(NaN == NaN);        // false (NaN is never equal to anything)

// The same with ===
console.log(false === 0);       // false
console.log(null === undefined);// false
β–Ά Output
true true false true true false true false false false false false

Converting Objects and Arrays to Strings

JavaScript
const arr = [1, 2, 3];
const obj = { name: "Alice", age: 30 };

// Array to string
console.log(String(arr));          // "1,2,3"
console.log(arr.toString());       // "1,2,3"
console.log(arr.join(" - "));      // "1 - 2 - 3"

// Object to string (not very useful)
console.log(String(obj));          // "[object Object]"
console.log(obj.toString());       // "[object Object]"

// JSON.stringify β€” proper object/array serialization
console.log(JSON.stringify(obj));  // '{"name":"Alice","age":30}'
console.log(JSON.stringify(obj, null, 2));
// Pretty-printed JSON with 2-space indent

// JSON.parse β€” convert JSON string back to object
const json = '{"name":"Bob","score":99}';
const parsed = JSON.parse(json);
console.log(parsed.name);          // "Bob"
β–Ά Output
1,2,3 1,2,3 1 - 2 - 3 [object Object] [object Object] {"name":"Alice","age":30} { "name": "Alice", "age": 30 } Bob
ℹ️
Common Coercion Bug: Form Input

HTML form inputs always return strings. If you read a number from an input field and try to add it to another number without converting, you get concatenation: input.value + 5 gives "105" instead of 15. Always use Number(input.value) or +input.value first.

πŸ‹οΈ Practical Exercise

  1. Convert the string "123" to a number three ways: Number(), parseInt(), and the unary + operator (+"123").
  2. Use !! to convert these to booleans and predict the result: 0, "", "0", [], null.
  3. Demonstrate the + operator coercion bug: "10" + 5 + 5 vs 10 + 5 + "5".
  4. Use JSON.stringify() to serialize an object and JSON.parse() to restore it.
  5. Write a guard for a function that receives user input: convert it to a number and return NaN feedback if the conversion fails.

πŸ”₯ Challenge Exercise

Create a function safeAdd(a, b) that takes two values (which might be strings or numbers), converts both to numbers, checks that neither is NaN, and returns their sum. If either can't be converted, return an error message string like "Error: 'hello' is not a valid number". Test it with safeAdd("5", 3), safeAdd("5.5", "2.2"), safeAdd("abc", 10), and safeAdd(null, 5).

πŸ“‹ Summary

  • Implicit coercion: JavaScript auto-converts types. The + operator concatenates if either operand is a string.
  • Explicit: String(), Number(), Boolean(), parseInt(), parseFloat().
  • Only 8 falsy values: false, 0, -0, 0n, "", null, undefined, NaN. Everything else is truthy.
  • Empty arrays [] and objects {} are truthy!
  • Use === always. The == coercion rules are complex and surprising.
  • Use JSON.stringify() to properly convert objects/arrays to strings.

Interview Questions

  • What are the falsy values in JavaScript?
  • What is the difference between implicit and explicit type conversion?
  • Why does "5" + 3 give "53" but "5" - 3 gives 2?
  • Is an empty array [] truthy or falsy?
  • How would you convert a value to boolean in JavaScript?

Frequently Asked Questions

Why is [] truthy but [] == false is also true? +

This is one of the most confusing JavaScript quirks. [] is truthy in boolean contexts (like if ([])). But [] == false uses loose equality, which converts [] to a number (via string): [] β†’ "" β†’ 0, and false β†’ 0, so 0 == 0 is true. This illustrates why using == is so dangerous β€” just use ===.

What does + in front of a value do? +

The unary + operator converts a value to a number, just like Number(): +"42" gives 42, +true gives 1, +"" gives 0, +"hello" gives NaN. It's a compact shorthand, but Number() is more readable β€” use whichever your team prefers.

Does JSON.stringify handle all JavaScript values? +

No. JSON.stringify cannot serialize: undefined (omitted from objects, becomes null in arrays), functions (silently omitted), Symbol values, circular references (throws an error), BigInt (throws a TypeError), and special objects like Date (converted to ISO string). For complex serialization needs, use a library like superjson.

What is the safest way to check if a value is null or undefined? +

Use value == null β€” this is one of the few good uses of loose equality. It returns true for both null and undefined but false for everything else (including 0, "", and false). Alternatively, use value === null || value === undefined for explicit clarity.

How do I check if a string represents a valid number? +

Use !Number.isNaN(Number(str)) && str.trim() !== "". The str.trim() !== "" check is necessary because Number("") and Number(" ") both return 0 instead of NaN. Or use a regex: /^-?\d+(\.\d+)?$/.test(str) for basic integer/float validation.