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.