Ooker
Ooker

Reputation: 3054

Why can for...in loop run on undefined?

Why does this code work?

for (const i in undefined) {}

From for...in - JavaScript | MDN:

The for...in statement iterates over all enumerable string properties of an object (ignoring properties keyed by symbols), including inherited enumerable properties.

But according to undefined - JavaScript | MDN, undefined has no enumerable property. So the for...in loop shouldn't work on it.

The deno-ts linter says:

The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'never'.

Upvotes: 2

Views: 93

Answers (1)

VLAZ
VLAZ

Reputation: 29088

But according to undefined - JavaScript | MDN, undefined has no enumerable property. So the for...in loop shouldn't work on it.

Looping over something that is "empty" means the loop is a no-op. Not that there would be an error. Consider this for..of example:

const arr = [];

console.log("start loop");
for (const item of arr) {
  console.log("item is", item);
}
console.log("end loop");

And with this consideration, let us look at for..in where the behaviour is the same:

const object = {};

console.log("start loop");
for (const key in object) {
  console.log("key is", key);
}
console.log("end loop");

Looping over an empty object with no enumerable properties using for..in does not error.

The same applies to undefined. It has no enumerable properties, so the loop is merely a no-op.

The deno-ts linter says:

The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'never'.

One of the things that linters do is detect potential problems. Writing a loop which is a guaranteed no-op does not seem like correct code. Same as if you had:

if (false)
    doSomething();

or maybe a bit more complex (so it is not as easy to spot)

if (x === 1 && x === 2)
    doSomething();

A linter should flag both of these for the same reason - the code is most likely a mistake because it is guaranteed to never execute.

Upvotes: 6

Related Questions