Some confusing JavaScript programs related to data types often asked in interviews, along with sorted explanations:
1. NaN Comparisons:
console.log(NaN === NaN);
console.log(NaN == NaN);
Explanation: Both comparisons return false. In JavaScript, NaN is not equal to itself.
2. null vs. undefined:
console.log(null == undefined);
console.log(null === undefined);
Explanation: null == undefined is true due to type coercion, but null === undefined is false because they are different types.
3. String to Boolean:
console.log('false' == false);
Explanation: This prints true. JavaScript performs type coercion, converting 'false' to false for the comparison.
4. Comparing Arrays:
console.log([] == []);
Explanation: This returns false. Arrays are reference types, and == compares references, not contents.
5. typeof NaN:
console.log(typeof NaN);
Explanation: typeof NaN returns 'number'. It’s a historical quirk.
6. The delete Operator:
var obj = { name: 'John' };
delete obj.name;
console.log(obj.name);
Explanation: delete obj.name removes the name property from obj. Accessing obj.name afterward returns undefined.
7. Object Property Names:
var obj = { 1: 'One', 2: 'Two' };
console.log(obj[1]);
Explanation: Property names are converted to strings. obj[1] and obj['1'] are equivalent.
8. Object Equality:
var obj1 = { a: 1 };
var obj2 = { a: 1 };
console.log(obj1 === obj2);
Explanation: obj1 and obj2 are distinct objects, so the comparison returns false.
9. NaN in Arrays:
var arr = [2, NaN, 'Hello', NaN, 42];
console.log(arr.indexOf(NaN));
Explanation: arr.indexOf(NaN) returns 1 because NaN is not equal to itself, so it finds the first occurrence.
10. parseFloat Behavior:
console.log(parseFloat('3.14.15'));
Explanation: This parses the initial part of the string as a floating-point number, resulting in 3.14. The second '15' is not part of the valid number.
11. The in Operator:
console.log('x' in { x: undefined });
Explanation: This returns true. The in operator checks for the presence of a property, regardless of its value.
12. Array length Property:
var arr = [1, 2, 3];
arr.length = 0;
console.log(arr[2]);
Explanation: This logs undefined. Setting arr.length to 0 removes all elements, leaving an empty array.
13. Object Keys Order:
var obj = { b: 2, c: 3, a: 1 };
console.log(Object.keys(obj));
Explanation: The order of keys in the result may not match the order of property insertion. In this case, it could be ['b', 'c', 'a'] or another order.
14. parseInt Behavior:
console.log(parseInt('07'));
Explanation: parseInt('07') treats '07' as an octal number, so it converts it to decimal, resulting in 7.
15. JSON Serialization:
var obj = { x: [10, undefined, null] };
console.log(JSON.stringify(obj));
Explanation: JSON.stringify omits undefined values, so the resulting string is {"x":[10,null]}.
16. Function Name Property:
function foo() {}
console.log(foo.name);
Explanation: foo.name returns 'foo', which is the name of the function.
17. Global Variables Inside Functions:
var x = 10;
function foo() {
console.log(x);
var x = 20;
}
foo();
Explanation: JavaScript has function-level scope and hoists variables. The local var x inside foo is hoisted and shadowing the global x, so it logs undefined.
18. The arguments Object:
function foo() {
console.log(arguments.length);
}
foo(1, 2, 3);
Explanation: This code logs 3. The arguments object holds the number of arguments passed to the function.
19. Prototypal Inheritance:
function Parent() {}
function Child() {}
Child.prototype = new Parent();
var child = new Child();
console.log(child instanceof Parent);
Explanation: The child is an instance of Child, but due to prototypal inheritance, it’s also considered an instance of Parent.
20. null and Object Creation:
var obj = Object.create(null);
console.log(obj.toString());
Explanation: This code throws an error because Object.create(null) creates an object without a prototype, so it doesn’t have a toString method.
21. Function Declarations vs. Expressions:
console.log(foo());
console.log(bar());
function foo() {
return 'Hello, Foo!';
}
var bar = function() {
return 'Hello, Bar!';
};
Explanation: foo is a function declaration and is hoisted. bar is a
22. typeof Array:
console.log(typeof []);
Explanation: This returns 'object', which is often unexpected. Arrays are a special type of object in JavaScript.
23. typeof null:
console.log(typeof null);
Explanation: This returns 'object'. It’s a historical quirk and considered a bug in JavaScript.
24. Symbol Comparison:
const sym1 = Symbol('foo');
const sym2 = Symbol('foo');
console.log(sym1 === sym2);
Explanation: Symbols are always unique, so sym1 and sym2 are not equal, resulting in false.
25. undefined in Ternary Operator:
console.log(undefined ? 'true' : 'false');
Explanation: This prints 'false'. In a ternary operator, undefined is treated as false.
26. Function Name Property with Arrow Function:
const func = () => {};
console.log(func.name);
Explanation: This prints an empty string ''. Arrow functions do not have a name property.
27. Math.min() and Math.max() with Arrays:
console.log(Math.min([10, 5, 20]));
console.log(Math.max([10, 5, 20]));
Explanation: Both statements return NaN. Math.min() and Math.max() expect individual arguments, not arrays.
28. Number Function with Strings:
console.log(Number('Hello'));
Explanation: This returns NaN. Number() attempts to convert the string to a number, but it fails for non-numeric strings.
29. undefined as a Variable Name:
var undefined = 'Hello';
console.log(undefined);
Explanation: This logs 'Hello'. You can assign a value to a variable named undefined.
30. Changing this with bind():
const obj = {
x: 42,
getX: function() {
return this.x;
}
};
const unboundGetX = obj.getX;
const boundGetX = unboundGetX.bind(obj);
console.log(boundGetX());
Explanation: This logs undefined. When unboundGetX is called, this is not bound to obj. Binding obj using bind() fixes the issue.
31. Parsing null with parseInt:
console.log(parseInt(null));
Explanation: This returns NaN. parseInt() expects a string argument.
32. Number.isNaN():
console.log(Number.isNaN('Hello'));
console.log(Number.isNaN(NaN));
Explanation: The first statement returns false. Number.isNaN() is strict and only returns true for NaN values.
33. Object Destructuring with Missing Properties:
const { a, b } = { a: 1 };
console.log(a, b);
Explanation: This logs 1 undefined. Destructuring assigns undefined to b because b doesn’t exist in the object.
34. The void Operator:
console.log(void 0);
Explanation: This returns undefined. The void operator evaluates its expression and returns undefined.
35. Adding Strings and Numbers:
console.log('2' + 2);
console.log('2' - 2);
Explanation: The first statement concatenates the strings, resulting in '22'. The second statement performs subtraction, resulting in 0.
36. Date Object Month Index:
const date = new Date('2022-03-10');
console.log(date.getMonth());
Explanation: This logs 2, which is the month index (0-based) for March.
37. Using typeof with null:
console.log(typeof null);
Explanation: This returns 'object'. It’s a historical quirk and considered a bug in JavaScript.
38. JSON.parse() with Double Quotes:
console.log(JSON.parse('"Hello"'));
Explanation: This returns 'Hello'. JSON.parse() expects double-quoted strings.
39. false Equality with 0:
console.log(false == 0);
Explanation: This returns true. JavaScript performs type coercion and considers false and 0 equal.
40. The in Operator with Arrays:
const arr = [10, 20, 30];
console.log(1 in arr);
Explanation: This returns true. The in operator checks if an index exists in the array.
41. Object Literals with Duplicate Properties:
const obj = { x: 10, x: 20 };
console.log(obj.x);
Explanation: This logs 20. Object literals can have duplicate properties, and the last one wins.
42. parseInt with Radix:
console.log(parseInt('10', 1));
console.log(parseInt('10', 10));
console.log(parseInt('10', 16));
Explanation: The first statement returns NaN because 1 is an invalid radix. The second statement returns 10. The third statement interprets '10' as hexadecimal and returns 16.
43. Math.max() with No Arguments:
console.log(Math.max());
Explanation: This returns -Infinity. Math.max() returns -Infinity when no arguments are provided.
44. Multiple Spaces in Strings:
console.log(' ' == ' ');
Explanation: This returns false. While multiple spaces visually look the same, they are different characters.
45. instanceof with Arrays:
console.log([] instanceof Array);
console.log([] instanceof Object);
Explanation: Both statements return true. Arrays are instances of both Array and Object in JavaScript.
46. Adding null and a Number:
console.log(null + 42);
Explanation: This returns 42. null is converted to 0 during numeric operations.
47. Floating-Point Precision:
console.log(0.1 + 0.2 === 0.3);
Explanation: This returns false. Floating-point arithmetic can result in small precision errors.
48. Array.isArray() with null:
console.log(Array.isArray(null));
Explanation: This returns false. null is not considered an array.
49. Array.prototype.toString() Behavior:
const arr = [1, 2, 3];
arr.toString = function() {
return 'Custom';
};
console.log(arr.toString());
Explanation: This logs 'Custom'. When toString is defined on an array, it overrides the default behavior.
50. Number.MAX_VALUE vs. Infinity:
console.log(Number.MAX_VALUE + 1 === Infinity);
Explanation: This returns true. Adding 1 to Number.MAX_VALUE results in Infinity.