π¨ JavaScript Β· Topic 4 of 20
Type Coercion & Equality β JavaScript Questions with Answers
30 practice questions on Type Coercion & Equality, each with the correct answer and a clear explanation of why it is right. Read through them as revision notes, or take this topic as an interactive quiz to test yourself.
2 easy Β· 12 medium Β· 16 hard Β· Part of JavaScript: The language of the web - basics to advanced, 20 topics.
Medium questions (12)
Q3. medium
Which values are FALSY in JavaScript?
if ("") { } // skipped
if ("0") { } // runs! non-empty string
if ([]) { } // runs! empty array is truthy
- A false, 0, -0, "", null, undefined, NaN (and 0n)
- B Only false
- C false, 0 and []
- D Everything except true
Answer: A β false, 0, -0, "", null, undefined, NaN (and 0n)
Those are the only falsy values - EVERYTHING else is truthy, including "0", "false", [], {} and negative numbers. Memorising this short list explains most if-statement surprises.
TruthyFalsy
Q7. medium
What is the output?
console.log(null == undefined, null === undefined);
if (value == null) { } // catches null AND undefined
- A true false
- B true true
- C false false
- D false true
Answer: A β true false
A special rule makes null and undefined loosely equal to each other (and to nothing else). Strictly they are different types. Handy: value == null tests for 'null OR undefined' in one check.
nullundefined
Q9. medium
What does Number("") return?
console.log(Number("")); // 0
console.log(Number(" ")); // 0
console.log(Number("abc")); // NaN
- A 0 - an empty string converts to zero
- B NaN
- C undefined
- D ""
Answer: A β 0 - an empty string converts to zero
Number("") and Number(" ") are both 0, which surprises people expecting NaN. Number("abc") is NaN. This is why empty form fields can silently become 0.
Number()Coercion
Q10. medium
What is the output?
console.log(Number(true), Number(false), Number(null));
console.log(Number(undefined)); // NaN
console.log(Number(null)); // 0
- A 1 0 0
- B true false null
- C 1 0 NaN
- D NaN NaN NaN
Answer: A β 1 0 0
true converts to 1, false to 0, and null to 0. (But Number(undefined) is NaN - another inconsistency between null and undefined.)
Number conversion
Q15. medium
What is the output?
console.log("10" > "9");
console.log("10" > "9"); // false - string compare
console.log(10 > 9); // true
console.log("10" > 9); // true - mixed types convert to number
- A false - two strings compare ALPHABETICALLY, and "1" comes before "9"
- B true
- C NaN
- D SyntaxError
Answer: A β false - two strings compare ALPHABETICALLY, and "1" comes before "9"
When both operands are strings, comparison is lexicographic (character by character), not numeric. "10" > "9" is false. Convert first: Number("10") > Number("9") is true.
String comparisonSorting
Q17. medium
What is the safest way to compare two values?
- A Use === (and !==) so no hidden conversion happens
- B Always use ==
- C Use = for comparison
- D Convert everything to strings first
Answer: A β Use === (and !==) so no hidden conversion happens
=== compares type and value with no surprises. The single accepted exception is x == null to catch both null and undefined at once.
Best practicesStrict equality
Q19. medium
How do you safely convert user input "42" to a number?
const n = Number(input);
if (Number.isNaN(n)) {
alert("Please enter a number");
}
- A Number(input) or parseInt(input, 10) - then check with Number.isNaN()
- B input.toNumber()
- C (int) input
- D input * "1"
Answer: A β Number(input) or parseInt(input, 10) - then check with Number.isNaN()
Number() is strict (rejects "42abc"); parseInt(str, 10) reads leading digits. Always pass the radix 10 to parseInt and verify the result is not NaN.
parseIntValidation
Q21. medium
What does String(null) return?
console.log("Value: " + null); // "Value: null"
- A "null" (the text)
- B ""
- C null
- D undefined
Answer: A β "null" (the text)
String() turns any value into readable text, including "null" and "undefined". That is why concatenating a null value shows the word null in the UI.
String()Concatenation
Q23. medium
How can you check whether a value is a real number (not NaN, not a numeric string)?
Number.isFinite(42); // true
Number.isFinite("42"); // false
Number.isFinite(NaN); // false
- A typeof v === "number" && !Number.isNaN(v) (or Number.isFinite(v))
- B typeof v === "number" only
- C v > 0
- D isNaN(v) === false
Answer: A β typeof v === "number" && !Number.isNaN(v) (or Number.isFinite(v))
typeof alone accepts NaN (whose type is "number"). Number.isFinite(v) is the neat one-call version - it rejects NaN, Infinity and non-numbers.
Number.isFiniteValidation
Q25. medium
What does JSON.parse() do with the string '{"a":1}'?
const obj = JSON.parse('{"a":1}');
console.log(obj.a); // 1
console.log(JSON.stringify(obj)); // '{"a":1}'
- A Converts JSON TEXT into a real JavaScript object
- B Converts an object into text
- C Validates the object
- D Deletes the object
Answer: A β Converts JSON TEXT into a real JavaScript object
JSON.parse turns text into objects (used on API responses); JSON.stringify does the reverse (used before sending or storing data).
JSONAPIs
Q27. medium
Which comparison is safe for checking if a variable exists and has a value?
- A if (value != null) - catches both null and undefined
- B if (value) - also rejects 0 and ""
- C if (value !== false)
- D if (typeof value)
Answer: A β if (value != null) - catches both null and undefined
if (value) rejects legitimate values like 0 and "". value != null (the one accepted use of loose equality) checks only for null/undefined. Modern alternative: value ?? fallback.
null checksNullish
Q29. medium
What does Object.is(NaN, NaN) return?
console.log(Object.is(NaN, NaN)); // true
console.log(NaN === NaN); // false
console.log(Object.is(0, -0)); // false
- A true - Object.is treats NaN as equal to itself, unlike ===
- B false
- C NaN
- D undefined
Answer: A β true - Object.is treats NaN as equal to itself, unlike ===
Object.is is like === with two fixes: NaN equals NaN, and +0 is NOT equal to -0. Useful for precise value comparison.
Object.isNaN
Hard questions (16)
Q4. hard
What is the output?
console.log(Boolean([]), Boolean({}));
if (arr.length === 0) { } // correct emptiness test
if (Object.keys(obj).length === 0) { }
- A true true - empty arrays and objects are TRUTHY
- B false false
- C true false
- D false true
Answer: A β true true - empty arrays and objects are TRUTHY
Any object - including an empty array or object - is truthy. To test emptiness check arr.length === 0 or Object.keys(obj).length === 0.
- This trips up people coming from Python, where [] is falsy.
TruthinessObjects
Q5. hard
What is the output?
console.log([] == false);
console.log([] == false); // true (coerced)
console.log(Boolean([])); // true (truthy)
console.log([] === false); // false (strict)
- A true - [] converts to "" then to 0, and false converts to 0
- B false
- C undefined
- D TypeError
Answer: A β true - [] converts to "" then to 0, and false converts to 0
Loose equality converts both sides to numbers: [] becomes "" becomes 0, and false becomes 0. So 0 == 0 is true - even though Boolean([]) is true! A perfect argument for using ===.
Loose equalityGotchas
Q6. hard
What is the output?
console.log("" == 0, "0" == 0, "" == "0");
- A true true false - == converts strings to numbers, but "" and "0" are different strings
- B true true true
- C false false false
- D false true false
Answer: A β true true false - == converts strings to numbers, but "" and "0" are different strings
"" converts to 0 (true), "0" converts to 0 (true), but comparing two STRINGS does no numeric conversion, so "" == "0" is false. Loose equality is not transitive - a classic demonstration of why to avoid it.
Loose equalityCoercion rules
Q8. hard
What is the output?
console.log(NaN == NaN, NaN === NaN);
- A false false - NaN is never equal to anything, including itself
- B true true
- C true false
- D SyntaxError
Answer: A β false false - NaN is never equal to anything, including itself
The IEEE floating-point standard defines NaN as unequal to everything. Test with Number.isNaN(x) or Object.is(x, NaN).
NaNNumber.isNaN
Q11. hard
What is the output?
console.log(true + true);
- A 2 - booleans convert to 1 and 0 in arithmetic
- B "truetrue"
- C true
- D NaN
Answer: A β 2 - booleans convert to 1 and 0 in arithmetic
Arithmetic coerces booleans to numbers: true is 1, so 1 + 1 = 2. A neat trick: array.filter(Boolean).length or summing booleans to count matches.
Boolean coercionArithmetic
Q12. hard
What is the output?
console.log([] + []);
console.log(typeof ([] + [])); // "string"
console.log([1,2] + [3]); // "1,23"
- A "" (an empty string) - both arrays convert to empty strings and concatenate
- B []
- C 0
- D NaN
Answer: A β "" (an empty string) - both arrays convert to empty strings and concatenate
The + operator converts objects to primitives; an array becomes its join(",") string, so [] becomes "". Empty + empty = empty string. The result is a string, not an array.
Array coercionGotchas
Q13. hard
What is the output?
console.log([] + {});
- A "[object Object]" - [] becomes "" and {} becomes "[object Object]"
- B "{}"
- C 0
- D TypeError
Answer: A β "[object Object]" - [] becomes "" and {} becomes "[object Object]"
A plain object's default string form is "[object Object]", so "" + "[object Object]" gives that famous string. Seeing it in your UI means you printed an object instead of its contents - use JSON.stringify() instead.
Object coerciontoString
Q14. hard
What is the output?
console.log("5" * "2");
- A 10 - both strings are converted to numbers
- B "52"
- C NaN
- D "10"
Answer: A β 10 - both strings are converted to numbers
*, -, / and % have only a numeric meaning, so both operands are converted. Only + is ambiguous because it also concatenates.
Numeric coercion
Q16. hard
Why does [10, 9, 100].sort() give [10, 100, 9]?
console.log([10, 9, 100].sort()); // [10, 100, 9]
console.log([10, 9, 100].sort((a,b) => a-b)); // [9, 10, 100]
- A sort() converts elements to STRINGS by default and sorts alphabetically
- B sort() is broken
- C It sorts by length
- D It sorts randomly
Answer: A β sort() converts elements to STRINGS by default and sorts alphabetically
The default sort compares string forms: "10" < "100" < "9". For numbers you must pass a comparator: sort((a, b) => a - b).
- One of the most common real-world JavaScript bugs.
sort()Comparator
Q18. hard
What is the output?
console.log("5" === 5, "5" == 5);
const input = "5"; // from a form
if (input === 5) { } // never runs!
if (Number(input) === 5) { } // correct
- A false true
- B true true
- C false false
- D true false
Answer: A β false true
Strict comparison fails because the types differ. Loose comparison converts the string to a number first, so it succeeds. Data from input fields and APIs is often a string - a frequent source of this bug.
FormsInput validation
Q20. hard
What is the output?
console.log(0.1 + 0.2 === 0.3);
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON); // true
- A false - floating-point maths gives 0.30000000000000004
- B true
- C NaN
- D SyntaxError
Answer: A β false - floating-point maths gives 0.30000000000000004
Binary floating point cannot represent 0.1 and 0.2 exactly. Compare with a tolerance: Math.abs(a - b) < Number.EPSILON, or work in integers (cents instead of rupees).
Floating pointNumber.EPSILON
Q22. hard
What is the output?
console.log(1 + "2" - 3);
- A 9 - 1 + "2" gives "12", then "12" - 3 converts back to 12 - 3
- B 0
- C "12-3"
- D NaN
Answer: A β 9 - 1 + "2" gives "12", then "12" - 3 converts back to 12 - 3
Left to right: + with a string concatenates to "12"; then - forces numeric conversion, giving 12 - 3 = 9. A perfect illustration of mixed coercion.
CoercionOperator order
Q24. hard
What is the output?
console.log(!!"false", !!"0", !!0);
const flag = "false";
if (flag) { } // runs! (truthy string)
if (flag === "true") { } // correct check
- A true true false - any non-empty string is truthy regardless of its content
- B false false false
- C true false false
- D false true true
Answer: A β true true false - any non-empty string is truthy regardless of its content
The strings "false" and "0" are non-empty, so they are truthy. Only the number 0 is falsy here. Reading "false" from an API and using it in an if is a common bug - compare explicitly instead.
TruthinessAPI data
Q26. hard
What is the output?
console.log(typeof ("5" - 3), typeof ("5" + 3));
- A "number" "string"
- B "string" "string"
- C "number" "number"
- D "string" "number"
Answer: A β "number" "string"
Subtraction always produces a number (2), while + with a string produces a string ("53"). Same operands, different result types - the essence of JavaScript coercion.
typeofCoercion
Q28. hard
What is the output?
console.log([1] == 1, [1,2] == "1,2");
- A true true - arrays convert to their comma-joined string, then compare
- B false false
- C true false
- D TypeError
Answer: A β true true - arrays convert to their comma-joined string, then compare
[1] becomes "1" then the number 1 - equal. [1,2] becomes "1,2", matching the string. Bizarre, but consistent with the coercion rules. Yet another reason to use ===.
Array coercionGotchas
Q30. hard
Why should you write === almost everywhere, in one sentence?
- A It compares without hidden conversions, so results are predictable and bug-free
- B It is faster to type
- C == was removed from the language
- D === works on more types
Answer: A β It compares without hidden conversions, so results are predictable and bug-free
Loose equality follows a complex conversion table that is not even transitive ("" == 0 and "0" == 0, but "" != "0"). Strict equality has one simple rule: same type, same value. Linters flag == for this reason.
Best practicesLinting