Back to Biomejs

useGuardForIn

src/content/docs/linter/rules/use-guard-for-in.mdx

latest4.4 KB
Original Source

import { Tabs, TabItem } from '@astrojs/starlight/components';

<Tabs> <TabItem label="JavaScript (and super languages)" icon="seti:javascript"> ## Summary - Rule available since: `v1.9.4` - Diagnostic Category: [`lint/suspicious/useGuardForIn`](/reference/diagnostics#diagnostic-category) - This rule isn't recommended, so you need to enable it. - This rule doesn't have a fix. - The default severity of this rule is [**warning**](/reference/diagnostics#warning). - Sources: - Same as [`guard-for-in`](https://eslint.org/docs/latest/rules/guard-for-in)

How to configure

json
{
	"linter": {
		"rules": {
			"suspicious": {
				"useGuardForIn": "error"
			}
		}
	}
}

Description

Require for-in loops to include an if statement.

Looping over objects with a for-in loop will include properties inherited through the prototype chain. This behavior can lead to unexpected items in your for loop.

For codebases that do not support ES2022, Object.prototype.hasOwnProperty.call(foo, key) can be used as a check that the property is not inherited.

For codebases that do support ES2022, Object.hasOwn(foo, key) can be used as a shorter and more reliable alternative.

Examples

Invalid

js
for (key in foo) {
  doSomething(key);
}
<pre class="language-text"><code class="language-text">code-block.js:1:1 <a href="https://biomejs.dev/linter/rules/use-guard-for-in">lint/suspicious/useGuardForIn</a> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ <strong><span style="color: Orange;">⚠</span></strong> <span style="color: Orange;">The body of a for-in should be wrapped in an &#96;if&#96; statement.</span> <strong><span style="color: Tomato;">&gt;</span></strong> <strong>1 │ </strong>for (key in foo) &#123; <strong> │ </strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong> <strong><span style="color: Tomato;">&gt;</span></strong> <strong>2 │ </strong> doSomething(key); <strong><span style="color: Tomato;">&gt;</span></strong> <strong>3 │ </strong>&#125; <strong> │ </strong><strong><span style="color: Tomato;">^</span></strong> <strong>4 │ </strong> <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">Looping over the object with for-in loop will include properties that are inherited through the prototype chain, the behaviour can lead to some unexpected items in your loop.</span> <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">To resolve this issue, add an if statement like &#96;if (Object.hasOwn(foo, key)) &#123;...&#125;&#96; to filter out the extraneous properties. </span> </code></pre>

Valid

js
for (key in foo) {
  if (Object.hasOwn(foo, key)) {
   doSomething(key);
  }
}
js
for (key in foo) {
  if (Object.prototype.hasOwnProperty.call(foo, key)) {
    doSomething(key);
  }
}
js
for (key in foo) {
  if ({}.hasOwnProperty.call(foo, key)) {
    doSomething(key);
  }
}
</TabItem> </Tabs>