← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Prototype Chain Errors & hasOwnProperty

javascript ES2022 Intermediate
debt(d3/e3/b5/t7)
d3 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'default linter catches the common case' (d3). ESLint can detect for...in loops without hasOwnProperty checks via built-in rules like no-prototype-builtins and no-restricted-syntax. The detection_hints confirm ESLint automation with the for...in pattern, making this a standard linter-level catch.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix is straightforward: replace for...in with Object.keys()/Object.entries() or use Object.hasOwn() instead of hasOwnProperty(). These are one-component refactors within isolated loops, not cross-cutting changes.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5). This choice affects iteration patterns throughout any JavaScript codebase. Developers must remember to use Object.keys() or add hasOwnProperty checks on every for...in usage; the prototype chain's invisible reach creates an ongoing cognitive load across multiple work streams, though it doesn't fundamentally reshape the system architecture.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception directly contradicts the developer's intuition: for...in iterates the entire prototype chain, not just own properties—the opposite of what the syntax suggests. This contradicts similar iteration patterns in other languages (for...in in Python, for...of in modern JS) and matches a serious gotcha that catches experienced developers unaware until they encounter inherited properties or prototype pollution.

About DEBT scoring →

TL;DR

Iterating objects with for...in includes inherited prototype properties — use hasOwnProperty() or Object.keys() to iterate only own properties.

Explanation

Every JS object has a prototype chain. for...in iterates all enumerable properties including inherited ones. This causes bugs when libraries add properties to Object.prototype (rare but real). Safe iteration: Object.keys(obj) — own enumerable string keys, Object.entries(obj) — key-value pairs, for (const key of Object.keys(obj)). hasOwnProperty() check: obj.hasOwnProperty(key) — but safe version is Object.prototype.hasOwnProperty.call(obj, key) since obj might not have hasOwnProperty (Object.create(null)). Object.create(null) creates a prototype-free object — safe for dictionaries.

Common Misconception

for...in only iterates own properties — it iterates ALL enumerable properties in the prototype chain, including inherited ones.

Why It Matters

Prototype pollution attacks (CVE-level vulnerabilities) work by injecting properties into Object.prototype that then appear in for...in loops across all objects.

Common Mistakes

  • Using for...in without hasOwnProperty check.
  • Calling obj.hasOwnProperty() directly — fails on Object.create(null) objects.
  • Not knowing Object.keys() only returns own enumerable properties.

Code Examples

✗ Vulnerable
const obj = { name: 'Paul', role: 'admin' };
for (const key in obj) {
    // Includes prototype properties if any were added:
    console.log(key, obj[key]);
}
✓ Fixed
// Safe iteration:
for (const [key, value] of Object.entries(obj)) {
    console.log(key, value); // Only own properties
}

// Safe hasOwnProperty call (works on Object.create(null) too):
const has = Object.prototype.hasOwnProperty.call(obj, 'name');

// Prototype-free object for dictionaries:
const dict = Object.create(null);
dict['key'] = 'value'; // No prototype chain

Added 22 Mar 2026
Edited 5 Apr 2026
Views 23
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S
No pings yet today
Amazonbot 7 Perplexity 5 Google 3 ChatGPT 1 Unknown AI 1 Majestic 1 Meta AI 1 Ahrefs 1
crawler 18 crawler_json 1 pre-tracking 1
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Low
⚡ Quick Fix
Replace for...in with Object.keys()/Object.entries(). Use Object.hasOwn(obj, key) (ES2022) instead of hasOwnProperty. Use Object.create(null) for dict-style objects.
📦 Applies To
javascript ES2022 web cli
🔗 Prerequisites
🔍 Detection Hints
for.*in.*\{
Auto-detectable: ✓ Yes eslint
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✓ Auto-fixable Fix: Low Context: Function
CWE-1321 CWE-915

✓ schema.org compliant