JavaScript Type Coercion Interview Questions (With Answers)
Easy Questions (1-10)
Section titled “Easy Questions (1-10)”1. Why does 5 + "3" return "53"?
Section titled “1. Why does 5 + "3" return "53"?”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:
- JavaScript sees the
+operator between a number (5) and a string (“3”) - The
+operator is overloaded - it can perform both addition and concatenation - When one operand is a string, JavaScript chooses concatenation
- The number 5 is implicitly converted to string “5”
- String concatenation occurs: “5” + “3” = “53”
2. Why does "10" - 5 return 5?
Section titled “2. Why does "10" - 5 return 5?”Solution:
console.log("10" - 5); // 5
Answer: 5
Explanation:
The subtraction operator (-) only works with numbers, so JavaScript performs implicit type conversion:
- JavaScript encounters the
-operator between a string (“10”) and a number (5) - The
-operator only performs numeric subtraction (no string equivalent) - JavaScript converts the string “10” to number 10 using
Number("10") - The conversion is successful because “10” represents a valid number
- Numeric subtraction occurs: 10 - 5 = 5
3. Why does Boolean(0) return false?
Section titled “3. Why does Boolean(0) return false?”Solution:
console.log(Boolean(0)); // false
Answer: false
Explanation: JavaScript has specific rules for converting values to boolean:
Boolean()constructor explicitly converts values to boolean type- JavaScript defines certain values as “falsy” - values that convert to false
- The number 0 is one of the falsy values in JavaScript
- Other falsy values include:
false,null,undefined,NaN,""(empty string) - All other values are “truthy” and convert to true
4. Why does String(null) return "null"?
Section titled “4. Why does String(null) return "null"?”Solution:
console.log(String(null)); // "null"
Answer: "null"
Explanation:
The String() constructor converts values to string representation:
String()is called withnullas argument- JavaScript has predefined string representations for primitive values
nullconverts to the string “null” (not an empty string)- This is different from
null.toString()which would throw an error String()is safer than.toString()because it handles null and undefined
5. Why does Number("123abc") return NaN?
Section titled “5. Why does Number("123abc") return NaN?”Solution:
console.log(Number("123abc")); // NaN
Answer: NaN
Explanation:
The Number() constructor attempts to convert strings to numbers:
Number()is called with “123abc” as argument- JavaScript tries to parse the entire string as a number
- The string starts with valid digits (123) but contains invalid characters (abc)
Number()requires the entire string to be a valid number representation- Since “123abc” is not a complete valid number, it returns
NaN(Not a Number) - This is different from
parseInt()which would return 123
6. Why does "5" * 2 return 10?
Section titled “6. Why does "5" * 2 return 10?”Solution:
console.log("5" * 2); // 10
Answer: 10
Explanation: The multiplication operator only works with numbers, triggering implicit conversion:
- JavaScript encounters
*operator between string “5” and number 2 - The
*operator only performs numeric multiplication - JavaScript converts string “5” to number 5 using
Number("5") - The conversion succeeds because “5” represents a valid number
- Numeric multiplication occurs: 5 * 2 = 10
7. Why does !!"hello" return true?
Section titled “7. Why does !!"hello" return true?”Solution:
console.log(!!"hello"); // true
Answer: true
Explanation:
Double negation (!!) is a common pattern to convert values to boolean:
- The first
!(logical NOT) converts “hello” to boolean and negates it - Non-empty strings are truthy, so
!"hello"becomes!truewhich isfalse - The second
!negates the result again:!falsebecomestrue - This pattern (
!!value) effectively converts any value to its boolean equivalent - It’s equivalent to
Boolean("hello")but more concise
8. Why does undefined + 1 return NaN?
Section titled “8. Why does undefined + 1 return NaN?”Solution:
console.log(undefined + 1); // NaN
Answer: NaN
Explanation:
When undefined is used in numeric operations, it converts to NaN:
- JavaScript encounters
+operator betweenundefinedand number 1 - Since both operands are non-strings, JavaScript attempts numeric addition
undefinedis converted to number usingNumber(undefined)Number(undefined)returnsNaN- Any arithmetic operation with
NaNresults inNaN - 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:
- JavaScript encounters
+between array[]and object{} - Both operands are objects, so JavaScript converts them to primitives
- Arrays convert to strings via
toString():[].toString()returns"" - Objects convert to strings via
toString():{}.toString()returns"[object Object]" - String concatenation occurs:
"" + "[object Object]" = "[object Object]"
10. Why does parseInt("10.5") return 10?
Section titled “10. Why does parseInt("10.5") return 10?”Solution:
console.log(parseInt("10.5")); // 10
Answer: 10
Explanation:
parseInt() parses strings for integer values:
parseInt()starts reading from the beginning of the string- It reads digit characters until it encounters a non-digit character
- It reads “1” and “0” successfully
- It encounters “.” which is not a valid digit for integers
- It stops parsing and returns the integer value found so far: 10
- The decimal portion is ignored (use
parseFloat()for decimal numbers)
Medium Questions (11-20)
Section titled “Medium Questions (11-20)”11. Why does [] == false return true?
Section titled “11. Why does [] == false return true?”Solution:
console.log([] == false); // true
Answer: true
Explanation:
Loose equality (==) performs type coercion following specific rules:
- JavaScript compares array
[]with booleanfalse - When comparing different types, JavaScript converts them to primitives
- Boolean
falseconverts to number:Number(false) = 0 - Array
[]converts to primitive viatoString():[].toString() = "" - Empty string
""converts to number:Number("") = 0 - Now comparing:
0 == 0which istrue - This is why
===(strict equality) is preferred to avoid unexpected coercion
12. Why does "02" - "01" return 1?
Section titled “12. Why does "02" - "01" return 1?”Solution:
console.log("02" - "01"); // 1
Answer: 1
Explanation: Subtraction operator converts string operands to numbers:
- JavaScript encounters
-operator between strings “02” and “01” - Subtraction only works with numbers, so type conversion occurs
"02"converts to number:Number("02") = 2"01"converts to number:Number("01") = 1- Leading zeros are ignored during string-to-number conversion
- Numeric subtraction:
2 - 1 = 1
13. Why does +true return 1?
Section titled “13. Why does +true return 1?”Solution:
console.log(+true); // 1
Answer: 1
Explanation:
The unary plus operator (+) converts values to numbers:
- Unary
+is applied to booleantrue - This operator explicitly converts its operand to a number
- Boolean
trueconverts to number 1 - Boolean
falsewould convert to number 0 - This is equivalent to
Number(true)but more concise - Common pattern for quick type conversion to number
14. Why does "5" - - "3" return 8?
Section titled “14. Why does "5" - - "3" return 8?”Solution:
console.log("5" - - "3"); // 8
Answer: 8
Explanation: This involves both subtraction and unary minus operators:
- Parse the expression:
"5" - (- "3") - First, the unary minus
-is applied to"3" "3"converts to number 3, then unary minus makes it -3- Now we have:
"5" - (-3) - Subtraction converts
"5"to number 5 - The operation becomes:
5 - (-3) = 5 + 3 = 8 - 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:
nullandundefinedare considered equal in loose equality (==)- This is explicitly defined in the ECMAScript specification
- They are the only values that equal each other with
==besides themselves - Neither converts to another type in this comparison
- However,
null === undefinedisfalse(strict equality) - This special rule exists because both represent “no value” concepts
16. Why does 1 + 2 + "3" return "33"?
Section titled “16. Why does 1 + 2 + "3" return "33"?”Solution:
console.log(1 + 2 + "3"); // "33"
Answer: "33"
Explanation: JavaScript evaluates expressions left to right with operator precedence:
- Expression is evaluated left to right:
(1 + 2) + "3" - First operation:
1 + 2(both numbers) =3 - Second operation:
3 + "3"(number + string) - When
+has a string operand, it performs concatenation - Number
3converts to string"3" - String concatenation:
"3" + "3" = "33" - 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:
Object.prototype.toStringis the basetoStringmethod- Using
.call([])applies this method to the array - This method returns a string in format
"[object Type]" - For arrays, it returns
"[object Array]" - This works because arrays override their own
toString()method - The original
Object.prototype.toStringreveals the true type - This pattern works for all JavaScript objects and primitives
18. Why does Number("") return 0?
Section titled “18. Why does Number("") return 0?”Solution:
console.log(Number("")); // 0
Answer: 0
Explanation: Empty string has a specific conversion rule to number:
Number()constructor converts empty string to number- Empty string
""is defined to convert to0 - This is different from
NaNwhich would indicate invalid conversion - Whitespace-only strings also convert to
0:Number(" ") = 0 - This behavior is consistent with mathematical operations
- 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:
String()constructor can safely convert symbols to strings- The symbol
Symbol("test")becomes string"Symbol(test)" - This is different from implicit conversion which would throw an error
Symbol("test") + ""would throw TypeErrorString()is the safe way to convert symbols to strings- The string representation shows the symbol’s description
20. Why does Boolean([]) return true?
Section titled “20. Why does Boolean([]) return true?”Solution:
console.log(Boolean([])); // true
Answer: true
Explanation: Objects (including arrays) are always truthy in JavaScript:
Boolean()constructor converts values to boolean- Arrays are objects in JavaScript
- All objects are truthy values, regardless of their contents
- Even empty arrays
[]convert totrue - This is different from array’s primitive conversion (
[] == falseis true) - Only primitive values can be falsy:
false,0,"",null,undefined,NaN
Hard Questions (21-35)
Section titled “Hard Questions (21-35)”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:
- Expression evaluates left to right:
([] + []) + {} - First operation:
[] + [] - Arrays convert to strings:
[].toString() = "" - String concatenation:
"" + "" = "" - Second operation:
"" + {} - Object converts to string:
{}.toString() = "[object Object]" - Final concatenation:
"" + "[object Object]" = "[object Object]"
22. Why does ~~"5.9" return 5?
Section titled “22. Why does ~~"5.9" return 5?”Solution:
console.log(~~"5.9"); // 5
Answer: 5
Explanation:
Double bitwise NOT (~~) is a fast way to truncate numbers:
- First
~performs bitwise NOT operation - Bitwise operations convert operands to 32-bit signed integers
"5.9"converts to number5.95.9truncates to integer5for bitwise operation~5performs bitwise NOT:~5 = -6- Second
~performs bitwise NOT again:~(-6) = 5 - This effectively removes decimal places (truncation, not rounding)
23. Why does "10" + 1 - 1 return 100?
Section titled “23. Why does "10" + 1 - 1 return 100?”Solution:
console.log("10" + 1 - 1); // 100
Answer: 100
Explanation: Operator precedence and associativity determine evaluation order:
+and-have same precedence and left-to-right associativity- Expression evaluates as:
(("10" + 1) - 1) - First operation:
"10" + 1 - String concatenation occurs:
"10" + 1 = "101" - Second operation:
"101" - 1 - Subtraction converts string to number:
Number("101") = 101 - 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:
0.1 + 0.2performs floating-point arithmetic- Binary representation cannot exactly represent 0.1 and 0.2
- The sum is approximately
0.30000000000000004 0.3has a slightly different binary representation- The comparison
0.30000000000000004 == 0.3is false - This is a common issue with floating-point numbers in programming
- Use
Math.abs(a - b) < Number.EPSILONfor 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:
- Inner
typeof 1is evaluated first typeof 1returns the string"number"- Outer
typeofoperates on the string"number" typeof "number"returns"string"- The
typeofoperator always returns a string - 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:
- Both operands are arrays, so JavaScript converts them to primitives
- Arrays convert to strings using
toString()method [1,2,3].toString()returns"1,2,3"[4,5,6].toString()returns"4,5,6"- String concatenation:
"1,2,3" + "4,5,6" = "1,2,34,5,6" - The
join()method is called internally with comma separator - 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:
new Date(2022, 0, 1)creates January 1, 2022new Date(2022, 0, 0)creates December 31, 2021 (day 0 of January)- Subtraction converts Date objects to numbers using
valueOf() - This returns milliseconds since January 1, 1970 UTC
- The difference is 24 hours in milliseconds
- 24 hours × 60 minutes × 60 seconds × 1000 milliseconds = 86,400,000
- Date arithmetic is useful for calculating time differences
28. Why does parseInt("1e2") return 1?
Section titled “28. Why does parseInt("1e2") return 1?”Solution:
console.log(parseInt("1e2")); // 1
Answer: 1
Explanation:
parseInt() parses character by character until non-digit is found:
parseInt()starts reading from the beginning of “1e2”- It reads “1” which is a valid digit
- It encounters “e” which is not a valid digit for integers
- It stops parsing and returns the integer found so far: 1
- Scientific notation “1e2” (which equals 100) is not recognized
- This is different from
Number("1e2")which would return 100 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:
- JavaScript encounters
+operator between object{}and array[] - Both operands are objects, so conversion to primitives occurs
- Object
{}converts to string:{}.toString() = "[object Object]" - Array
[]converts to string:[].toString() = "" - String concatenation:
"[object Object]" + "" = "[object Object]" - Note: In some contexts (like statement blocks),
{}might be interpreted as a block statement
30. Why does "5" * "2" return 10?
Section titled “30. Why does "5" * "2" return 10?”Solution:
console.log("5" * "2"); // 10
Answer: 10
Explanation: Multiplication operator converts both operands to numbers:
- JavaScript encounters
*operator between strings “5” and “2” - Multiplication only works with numbers, so conversion occurs
"5"converts to number:Number("5") = 5"2"converts to number:Number("2") = 2- Numeric multiplication:
5 * 2 = 10 - All arithmetic operators except
+(which can concatenate) convert to numbers
31. Why does !"false" return false?
Section titled “31. Why does !"false" return false?”Solution:
console.log(!"false"); // false
Answer: false
Explanation: The logical NOT operator converts its operand to boolean first:
!operator is applied to string"false"- First, the string is converted to boolean
- Non-empty strings are truthy in JavaScript
Boolean("false")returnstrue(the string is not empty)!negates the boolean:!true = false- The content of the string doesn’t matter, only whether it’s empty
- 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:
Number.isNaN()checks if the value is exactlyNaN- It does NOT convert the argument to a number first
- The string
"NaN"is not the same as the valueNaN Number.isNaN()returnstrueonly for actualNaNvalues- This is different from global
isNaN()which converts first isNaN("NaN")would returntruebecauseNumber("NaN")isNaNNumber.isNaN()is more reliable for checking actualNaNvalues
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:
Array.prototypeis the prototype object for all arrays- In JavaScript,
Array.prototypeis actually an array instance Array.isArray()checks if the object is an array- Since
Array.prototypeis an array, it returnstrue - This is specified in the ECMAScript specification
- You can verify:
Array.prototype.lengthreturns0 - This design allows array methods to be called on the prototype
34. Why does +[] return 0?
Section titled “34. Why does +[] return 0?”Solution:
console.log(+[]); // 0
Answer: 0
Explanation: Unary plus converts array to number through string conversion:
- Unary
+operator converts its operand to number - Array
[]first converts to primitive (string) [].toString()returns empty string""Number("")converts empty string to0- Therefore:
+[] = Number([].toString()) = Number("") = 0 - This is equivalent to
Number([])which also returns0
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:
typeof nullreturns the string"object"- This is widely considered a bug in JavaScript
- The comparison
"object" == "object"istrue - This behavior exists since JavaScript’s creation and cannot be changed
- It would break existing code if fixed
- Use
value === nullto check for null specifically - Or use
typeof value === "object" && value !== nullfor actual objects