Some confusing JavaScript programs often asked in interviews, along with sorted explanations:
1. Closure within a Loop:
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
Explanation: Due to JavaScript’s closure behavior, this code prints 5 five times. The setTimeout callbacks capture the final value of i.
2. NaN Comparisons:
console.log(NaN === NaN);
console.log(NaN == NaN);
Explanation: Both comparisons return false. In JavaScript, NaN is not equal to itself.
3. this in an Arrow Function:
const obj = {
value: 42,
getValue: () => {
console.log(this.value);
}
};
obj.getValue();
Explanation: Arrow functions do not have their own this context. this in the arrow function refers to the outer context, which may not have a value property.
4. Object Key Types:
const key1 = { a: 1 };
const key2 = { b: 2 };
const obj = {};
obj[key1] = 'Hello';
obj[key2] = 'World';
console.log(obj[key1]);
Explanation: Object keys are converted to strings. Both key1 and key2 become [object Object], so the last assignment overwrites the first one.
5. 0.1 + 0.2 Precision:
console.log(0.1 + 0.2 === 0.3);
Explanation: This prints false because of floating-point precision issues. In JavaScript, 0.1 + 0.2 is not exactly equal to 0.3.
6. 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.
7. 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 function expression and is not hoisted, so calling it before the assignment results in an error.
8. 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.
9. 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.
10. 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.
11. parseInt Behavior:
console.log(parseInt('07'));
Explanation: parseInt('07') treats '07' as an octal number, so it converts it to decimal, resulting in 7.
12. 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]}.
13. 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.
14. 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.
15. typeof NaN:
console.log(typeof NaN);
Explanation: typeof NaN returns 'number'. It’s a historical quirk.
16. String to Boolean:
console.log('false' == false);
Explanation: This prints true. JavaScript performs type coercion, converting 'false' to false for the comparison.
17. 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.
18. JavaScript 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. Comparing Arrays:
console.log([] == []);
Explanation: This returns false. Arrays are reference types, and == compares references, not contents.
20. 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.
21. Function Name Property:
function foo() {}
console.log(foo.name);
Explanation: foo.name returns 'foo', which is the name of the function.
22. Object.create(null):
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.
23. 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.
24. 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.
25. 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.