Skip to content

JavaScript Type Coercion Interview Questions (With Answers)

Solution:

console.log(5 + "3"); // "53"

Answer: "53"

Explanation: When JavaScript encounters the + operator with a number and a string, it performs string concatenation rather than numeric addition. Here’s the step-by-step process:

  1. JavaScript sees the + operator between a number (5) and a string (“3”)
  2. The + operator is overloaded - it can perform both addition and concatenation
  3. When one operand is a string, JavaScript chooses concatenation
  4. The number 5 is implicitly converted to string “5”
  5. String concatenation occurs: “5” + “3” = “53”

Solution:

console.log("10" - 5); // 5

Answer: 5

Explanation: The subtraction operator (-) only works with numbers, so JavaScript performs implicit type conversion:

  1. JavaScript encounters the - operator between a string (“10”) and a number (5)
  2. The - operator only performs numeric subtraction (no string equivalent)
  3. JavaScript converts the string “10” to number 10 using Number("10")
  4. The conversion is successful because “10” represents a valid number
  5. Numeric subtraction occurs: 10 - 5 = 5

Solution:

console.log(Boolean(0)); // false

Answer: false

Explanation: JavaScript has specific rules for converting values to boolean:

  1. Boolean() constructor explicitly converts values to boolean type
  2. JavaScript defines certain values as “falsy” - values that convert to false
  3. The number 0 is one of the falsy values in JavaScript
  4. Other falsy values include: false, null, undefined, NaN, "" (empty string)
  5. All other values are “truthy” and convert to true

Solution:

console.log(String(null)); // "null"

Answer: "null"

Explanation: The String() constructor converts values to string representation:

  1. String() is called with null as argument
  2. JavaScript has predefined string representations for primitive values
  3. null converts to the string “null” (not an empty string)
  4. This is different from null.toString() which would throw an error
  5. String() is safer than .toString() because it handles null and undefined

Solution:

console.log(Number("123abc")); // NaN

Answer: NaN

Explanation: The Number() constructor attempts to convert strings to numbers:

  1. Number() is called with “123abc” as argument
  2. JavaScript tries to parse the entire string as a number
  3. The string starts with valid digits (123) but contains invalid characters (abc)
  4. Number() requires the entire string to be a valid number representation
  5. Since “123abc” is not a complete valid number, it returns NaN (Not a Number)
  6. This is different from parseInt() which would return 123

Solution:

console.log("5" * 2); // 10

Answer: 10

Explanation: The multiplication operator only works with numbers, triggering implicit conversion:

  1. JavaScript encounters * operator between string “5” and number 2
  2. The * operator only performs numeric multiplication
  3. JavaScript converts string “5” to number 5 using Number("5")
  4. The conversion succeeds because “5” represents a valid number
  5. Numeric multiplication occurs: 5 * 2 = 10

Solution:

console.log(!!"hello"); // true

Answer: true

Explanation: Double negation (!!) is a common pattern to convert values to boolean:

  1. The first ! (logical NOT) converts “hello” to boolean and negates it
  2. Non-empty strings are truthy, so !"hello" becomes !true which is false
  3. The second ! negates the result again: !false becomes true
  4. This pattern (!!value) effectively converts any value to its boolean equivalent
  5. It’s equivalent to Boolean("hello") but more concise

Solution:

console.log(undefined + 1); // NaN

Answer: NaN

Explanation: When undefined is used in numeric operations, it converts to NaN:

  1. JavaScript encounters + operator between undefined and number 1
  2. Since both operands are non-strings, JavaScript attempts numeric addition
  3. undefined is converted to number using Number(undefined)
  4. Number(undefined) returns NaN
  5. Any arithmetic operation with NaN results in NaN
  6. Therefore: NaN + 1 = NaN

9. Why does [] + {} return "[object Object]"?

Section titled “9. Why does [] + {} return "[object Object]"?”

Solution:

console.log([] + {}); // "[object Object]"

Answer: "[object Object]"

Explanation: When objects are used with + operator, they’re converted to primitives:

  1. JavaScript encounters + between array [] and object {}
  2. Both operands are objects, so JavaScript converts them to primitives
  3. Arrays convert to strings via toString(): [].toString() returns ""
  4. Objects convert to strings via toString(): {}.toString() returns "[object Object]"
  5. String concatenation occurs: "" + "[object Object]" = "[object Object]"

Solution:

console.log(parseInt("10.5")); // 10

Answer: 10

Explanation: parseInt() parses strings for integer values:

  1. parseInt() starts reading from the beginning of the string
  2. It reads digit characters until it encounters a non-digit character
  3. It reads “1” and “0” successfully
  4. It encounters “.” which is not a valid digit for integers
  5. It stops parsing and returns the integer value found so far: 10
  6. The decimal portion is ignored (use parseFloat() for decimal numbers)

Solution:

console.log([] == false); // true

Answer: true

Explanation: Loose equality (==) performs type coercion following specific rules:

  1. JavaScript compares array [] with boolean false
  2. When comparing different types, JavaScript converts them to primitives
  3. Boolean false converts to number: Number(false) = 0
  4. Array [] converts to primitive via toString(): [].toString() = ""
  5. Empty string "" converts to number: Number("") = 0
  6. Now comparing: 0 == 0 which is true
  7. This is why === (strict equality) is preferred to avoid unexpected coercion

Solution:

console.log("02" - "01"); // 1

Answer: 1

Explanation: Subtraction operator converts string operands to numbers:

  1. JavaScript encounters - operator between strings “02” and “01”
  2. Subtraction only works with numbers, so type conversion occurs
  3. "02" converts to number: Number("02") = 2
  4. "01" converts to number: Number("01") = 1
  5. Leading zeros are ignored during string-to-number conversion
  6. Numeric subtraction: 2 - 1 = 1

Solution:

console.log(+true); // 1

Answer: 1

Explanation: The unary plus operator (+) converts values to numbers:

  1. Unary + is applied to boolean true
  2. This operator explicitly converts its operand to a number
  3. Boolean true converts to number 1
  4. Boolean false would convert to number 0
  5. This is equivalent to Number(true) but more concise
  6. Common pattern for quick type conversion to number

Solution:

console.log("5" - - "3"); // 8

Answer: 8

Explanation: This involves both subtraction and unary minus operators:

  1. Parse the expression: "5" - (- "3")
  2. First, the unary minus - is applied to "3"
  3. "3" converts to number 3, then unary minus makes it -3
  4. Now we have: "5" - (-3)
  5. Subtraction converts "5" to number 5
  6. The operation becomes: 5 - (-3) = 5 + 3 = 8
  7. Subtracting a negative number is equivalent to addition

15. Why does null == undefined return true?

Section titled “15. Why does null == undefined return true?”

Solution:

console.log(null == undefined); // true

Answer: true

Explanation: This is a special case in JavaScript’s equality rules:

  1. null and undefined are considered equal in loose equality (==)
  2. This is explicitly defined in the ECMAScript specification
  3. They are the only values that equal each other with == besides themselves
  4. Neither converts to another type in this comparison
  5. However, null === undefined is false (strict equality)
  6. This special rule exists because both represent “no value” concepts

Solution:

console.log(1 + 2 + "3"); // "33"

Answer: "33"

Explanation: JavaScript evaluates expressions left to right with operator precedence:

  1. Expression is evaluated left to right: (1 + 2) + "3"
  2. First operation: 1 + 2 (both numbers) = 3
  3. Second operation: 3 + "3" (number + string)
  4. When + has a string operand, it performs concatenation
  5. Number 3 converts to string "3"
  6. String concatenation: "3" + "3" = "33"
  7. Different from 1 + (2 + "3") which would be "123"

17. Why does Object.prototype.toString.call([]) return "[object Array]"?

Section titled “17. Why does Object.prototype.toString.call([]) return "[object Array]"?”

Solution:

console.log(Object.prototype.toString.call([])); // "[object Array]"

Answer: "[object Array]"

Explanation: This is the reliable way to determine object types in JavaScript:

  1. Object.prototype.toString is the base toString method
  2. Using .call([]) applies this method to the array
  3. This method returns a string in format "[object Type]"
  4. For arrays, it returns "[object Array]"
  5. This works because arrays override their own toString() method
  6. The original Object.prototype.toString reveals the true type
  7. This pattern works for all JavaScript objects and primitives

Solution:

console.log(Number("")); // 0

Answer: 0

Explanation: Empty string has a specific conversion rule to number:

  1. Number() constructor converts empty string to number
  2. Empty string "" is defined to convert to 0
  3. This is different from NaN which would indicate invalid conversion
  4. Whitespace-only strings also convert to 0: Number(" ") = 0
  5. This behavior is consistent with mathematical operations
  6. Empty string is considered “zero-like” in numeric context

19. Why does String(Symbol("test")) return "Symbol(test)"?

Section titled “19. Why does String(Symbol("test")) return "Symbol(test)"?”

Solution:

console.log(String(Symbol("test"))); // "Symbol(test)"

Answer: "Symbol(test)"

Explanation: Symbols have special string conversion rules:

  1. String() constructor can safely convert symbols to strings
  2. The symbol Symbol("test") becomes string "Symbol(test)"
  3. This is different from implicit conversion which would throw an error
  4. Symbol("test") + "" would throw TypeError
  5. String() is the safe way to convert symbols to strings
  6. The string representation shows the symbol’s description

Solution:

console.log(Boolean([])); // true

Answer: true

Explanation: Objects (including arrays) are always truthy in JavaScript:

  1. Boolean() constructor converts values to boolean
  2. Arrays are objects in JavaScript
  3. All objects are truthy values, regardless of their contents
  4. Even empty arrays [] convert to true
  5. This is different from array’s primitive conversion ([] == false is true)
  6. Only primitive values can be falsy: false, 0, "", null, undefined, NaN

21. Why does [] + [] + {} return "[object Object]"?

Section titled “21. Why does [] + [] + {} return "[object Object]"?”

Solution:

console.log([] + [] + {}); // "[object Object]"

Answer: "[object Object]"

Explanation: This involves multiple object-to-primitive conversions:

  1. Expression evaluates left to right: ([] + []) + {}
  2. First operation: [] + []
  3. Arrays convert to strings: [].toString() = ""
  4. String concatenation: "" + "" = ""
  5. Second operation: "" + {}
  6. Object converts to string: {}.toString() = "[object Object]"
  7. Final concatenation: "" + "[object Object]" = "[object Object]"

Solution:

console.log(~~"5.9"); // 5

Answer: 5

Explanation: Double bitwise NOT (~~) is a fast way to truncate numbers:

  1. First ~ performs bitwise NOT operation
  2. Bitwise operations convert operands to 32-bit signed integers
  3. "5.9" converts to number 5.9
  4. 5.9 truncates to integer 5 for bitwise operation
  5. ~5 performs bitwise NOT: ~5 = -6
  6. Second ~ performs bitwise NOT again: ~(-6) = 5
  7. This effectively removes decimal places (truncation, not rounding)

Solution:

console.log("10" + 1 - 1); // 100

Answer: 100

Explanation: Operator precedence and associativity determine evaluation order:

  1. + and - have same precedence and left-to-right associativity
  2. Expression evaluates as: (("10" + 1) - 1)
  3. First operation: "10" + 1
  4. String concatenation occurs: "10" + 1 = "101"
  5. Second operation: "101" - 1
  6. Subtraction converts string to number: Number("101") = 101
  7. Final result: 101 - 1 = 100

24. Why does 0.1 + 0.2 == 0.3 return false?

Section titled “24. Why does 0.1 + 0.2 == 0.3 return false?”

Solution:

console.log(0.1 + 0.2 == 0.3); // false

Answer: false

Explanation: This demonstrates floating-point precision issues:

  1. 0.1 + 0.2 performs floating-point arithmetic
  2. Binary representation cannot exactly represent 0.1 and 0.2
  3. The sum is approximately 0.30000000000000004
  4. 0.3 has a slightly different binary representation
  5. The comparison 0.30000000000000004 == 0.3 is false
  6. This is a common issue with floating-point numbers in programming
  7. Use Math.abs(a - b) < Number.EPSILON for precise comparisons

25. Why does typeof (typeof 1) return "string"?

Section titled “25. Why does typeof (typeof 1) return "string"?”

Solution:

console.log(typeof (typeof 1)); // "string"

Answer: "string"

Explanation: The typeof operator returns a string representation of the type:

  1. Inner typeof 1 is evaluated first
  2. typeof 1 returns the string "number"
  3. Outer typeof operates on the string "number"
  4. typeof "number" returns "string"
  5. The typeof operator always returns a string
  6. Possible return values: "undefined", "boolean", "number", "string", "object", "function", "symbol", "bigint"

26. Why does [1,2,3] + [4,5,6] return "1,2,34,5,6"?

Section titled “26. Why does [1,2,3] + [4,5,6] return "1,2,34,5,6"?”

Solution:

console.log([1,2,3] + [4,5,6]); // "1,2,34,5,6"

Answer: "1,2,34,5,6"

Explanation: Array-to-string conversion occurs with the + operator:

  1. Both operands are arrays, so JavaScript converts them to primitives
  2. Arrays convert to strings using toString() method
  3. [1,2,3].toString() returns "1,2,3"
  4. [4,5,6].toString() returns "4,5,6"
  5. String concatenation: "1,2,3" + "4,5,6" = "1,2,34,5,6"
  6. The join() method is called internally with comma separator
  7. Use [...array1, ...array2] for actual array concatenation

27. Why does new Date(2022, 0, 1) - new Date(2022, 0, 0) return 86400000?

Section titled “27. Why does new Date(2022, 0, 1) - new Date(2022, 0, 0) return 86400000?”

Solution:

console.log(new Date(2022, 0, 1) - new Date(2022, 0, 0)); // 86400000

Answer: 86400000

Explanation: Date objects convert to numbers representing milliseconds since Unix epoch:

  1. new Date(2022, 0, 1) creates January 1, 2022
  2. new Date(2022, 0, 0) creates December 31, 2021 (day 0 of January)
  3. Subtraction converts Date objects to numbers using valueOf()
  4. This returns milliseconds since January 1, 1970 UTC
  5. The difference is 24 hours in milliseconds
  6. 24 hours × 60 minutes × 60 seconds × 1000 milliseconds = 86,400,000
  7. Date arithmetic is useful for calculating time differences

Solution:

console.log(parseInt("1e2")); // 1

Answer: 1

Explanation: parseInt() parses character by character until non-digit is found:

  1. parseInt() starts reading from the beginning of “1e2”
  2. It reads “1” which is a valid digit
  3. It encounters “e” which is not a valid digit for integers
  4. It stops parsing and returns the integer found so far: 1
  5. Scientific notation “1e2” (which equals 100) is not recognized
  6. This is different from Number("1e2") which would return 100
  7. parseInt() is literal character parsing, not mathematical evaluation

29. Why does {} + [] return "[object Object]"?

Section titled “29. Why does {} + [] return "[object Object]"?”

Solution:

console.log({} + []); // "[object Object]"

Answer: "[object Object]"

Explanation: Object-to-primitive conversion rules apply:

  1. JavaScript encounters + operator between object {} and array []
  2. Both operands are objects, so conversion to primitives occurs
  3. Object {} converts to string: {}.toString() = "[object Object]"
  4. Array [] converts to string: [].toString() = ""
  5. String concatenation: "[object Object]" + "" = "[object Object]"
  6. Note: In some contexts (like statement blocks), {} might be interpreted as a block statement

Solution:

console.log("5" * "2"); // 10

Answer: 10

Explanation: Multiplication operator converts both operands to numbers:

  1. JavaScript encounters * operator between strings “5” and “2”
  2. Multiplication only works with numbers, so conversion occurs
  3. "5" converts to number: Number("5") = 5
  4. "2" converts to number: Number("2") = 2
  5. Numeric multiplication: 5 * 2 = 10
  6. All arithmetic operators except + (which can concatenate) convert to numbers

Solution:

console.log(!"false"); // false

Answer: false

Explanation: The logical NOT operator converts its operand to boolean first:

  1. ! operator is applied to string "false"
  2. First, the string is converted to boolean
  3. Non-empty strings are truthy in JavaScript
  4. Boolean("false") returns true (the string is not empty)
  5. ! negates the boolean: !true = false
  6. The content of the string doesn’t matter, only whether it’s empty
  7. Only empty string "" would be falsy

32. Why does Number.isNaN("NaN") return false?

Section titled “32. Why does Number.isNaN("NaN") return false?”

Solution:

console.log(Number.isNaN("NaN")); // false

Answer: false

Explanation: Number.isNaN() is strict and doesn’t perform type conversion:

  1. Number.isNaN() checks if the value is exactly NaN
  2. It does NOT convert the argument to a number first
  3. The string "NaN" is not the same as the value NaN
  4. Number.isNaN() returns true only for actual NaN values
  5. This is different from global isNaN() which converts first
  6. isNaN("NaN") would return true because Number("NaN") is NaN
  7. Number.isNaN() is more reliable for checking actual NaN values

33. Why does Array.isArray(Array.prototype) return true?

Section titled “33. Why does Array.isArray(Array.prototype) return true?”

Solution:

console.log(Array.isArray(Array.prototype)); // true

Answer: true

Explanation: Array.prototype is itself an array object:

  1. Array.prototype is the prototype object for all arrays
  2. In JavaScript, Array.prototype is actually an array instance
  3. Array.isArray() checks if the object is an array
  4. Since Array.prototype is an array, it returns true
  5. This is specified in the ECMAScript specification
  6. You can verify: Array.prototype.length returns 0
  7. This design allows array methods to be called on the prototype

Solution:

console.log(+[]); // 0

Answer: 0

Explanation: Unary plus converts array to number through string conversion:

  1. Unary + operator converts its operand to number
  2. Array [] first converts to primitive (string)
  3. [].toString() returns empty string ""
  4. Number("") converts empty string to 0
  5. Therefore: +[] = Number([].toString()) = Number("") = 0
  6. This is equivalent to Number([]) which also returns 0

35. Why does typeof null == "object" return true?

Section titled “35. Why does typeof null == "object" return true?”

Solution:

console.log(typeof null == "object"); // true

Answer: true

Explanation: This is a famous JavaScript quirk that persists for historical reasons:

  1. typeof null returns the string "object"
  2. This is widely considered a bug in JavaScript
  3. The comparison "object" == "object" is true
  4. This behavior exists since JavaScript’s creation and cannot be changed
  5. It would break existing code if fixed
  6. Use value === null to check for null specifically
  7. Or use typeof value === "object" && value !== null for actual objects