Some confusing JavaScript programs

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.