[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"verticals":3,"quiz-object-hasown-safe-property-check":32,"quiz-article-object-hasown-safe-property-check":48},[4,20],{"id":5,"slug":6,"name":7,"tagline":8,"description":9,"accentFrom":10,"accentTo":11,"icon":12,"defaultLocale":13,"locales":14,"features":16,"position":19},"019fe637-3d33-714b-b57f-23e163ffca0c","dev","Web Development","Build. Learn. Ship.","Practical courses, engineering-grade articles and open-source tools for people who ship.","violet-500","cyan-400","◇","en",[13,15],"fa",{"courses":17,"paths":17,"articles":17,"exams":18,"flashcards":18,"packages":17,"community":17,"certificates":17,"teams":17,"commerce":17},true,false,0,{"id":21,"slug":22,"name":23,"tagline":24,"description":25,"accentFrom":26,"accentTo":10,"icon":27,"defaultLocale":13,"locales":28,"features":30,"position":31},"019fe637-3dc2-754c-8657-0f175bfee7c6","lang","Languages","Learn a language the way you learn a codebase.","Structured paths, listening drills and spaced repetition that actually sticks.","amber-400","⌘",[13,15,29],"es",{"courses":17,"paths":17,"articles":18,"exams":18,"flashcards":18,"packages":18,"community":17,"certificates":18,"teams":18,"commerce":17},2,{"id":33,"slug":34,"kind":35,"title":36,"description":37,"config":38,"verticalId":5,"vertical":43,"course":40,"_count":44,"access":45,"attempts":47,"questionCount":39},"019ff19b-f090-764c-8d1a-83c0f89429bb","object-hasown-safe-property-check","PRACTICE_QUIZ","Object.hasOwn() — safe property ownership checks","Object.hasOwn() is the ES2022 replacement for obj.hasOwnProperty(key). These questions check the two failure modes of the classic pattern, what Object.hasOwn() does differently, when for...in needs it, how it behaves in TypeScript, and what browser versions ship it.",{"questionCount":39,"timeLimitSec":40,"shuffleQuestions":18,"shuffleOptions":17,"negativeMarking":19,"passScorePct":41,"maxAttempts":40,"revealAnswers":42,"allowFlagging":18,"allowBacktracking":17},8,null,70,"AFTER_SUBMIT",{"slug":6,"name":7},{"questions":39},{"allowed":17,"reason":46},"FREE",[],{"id":49,"slug":34,"title":50,"subtitle":40,"excerpt":51,"coverUrl":52,"locale":13,"readingMinutes":53,"publishedAt":54,"viewCount":55,"likeCount":19,"commentCount":19,"author":56,"vertical":61,"topic":62,"tags":65,"_count":77,"playground":79,"body":81,"bodyMd":259,"seo":260,"translationGroupId":264,"thread":265,"assessments":267,"translations":270,"quiz":272},"019ff19b-f047-748a-800d-00912a4d95c9","You use `obj.hasOwnProperty(key)` to check property ownership. It can silently fail. `Object.hasOwn()` is the safe replacement.","Two real cases where `obj.hasOwnProperty(key)` throws or returns wrong results — and why `Object.hasOwn(obj, key)` is the ES2022 fix that ESLint's `no-prototype-builtins` rule has been nudging you toward for years.","\u002Fmedia\u002Fcovers\u002Fobject-hasown-safe-property-check.png",4,"2026-08-06T08:44:20.722Z",13,{"id":57,"name":58,"username":59,"avatarUrl":40,"headline":60},"019fe637-3c25-7088-9034-39c9f15dc3c8","Parsa Jiravand","parsa","Frontend engineer · building bestpractic",{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},"javascript","JavaScript",[66,68,71,74],{"slug":63,"name":67,"color":40},"Javascript",{"slug":69,"name":70,"color":40},"webdev","Webdev",{"slug":72,"name":73,"color":40},"frontend","Frontend",{"slug":75,"name":76,"color":40},"typescript","Typescript",{"assessments":78},1,{"slug":34,"title":80},"Object.hasOwn() — interactive playground",{"blocks":82,"version":78},[83,87,93,96,101,104,108,111,114,118,121,124,127,131,134,137,140,144,148,151,155,158,161,164,168,171,174,178,181,185,188,191,196,199,202,205,208,211,214,217,220,223,226,229,232,235,238,241,244,247,250],{"id":84,"html":85,"type":86},"b1","\u003Cp>Every JavaScript codebase has this pattern somewhere:\u003C\u002Fp>","paragraph",{"id":88,"code":89,"type":90,"language":91,"highlight":92},"b2","if (obj.hasOwnProperty(key)) {\n  \u002F\u002F ...\n}","code","js",[],{"id":94,"html":95,"type":86},"b3","\u003Cp>It&#39;s idiomatic, it&#39;s readable, and most of the time it works. But there are two specific situations where it silently fails — one throws, one returns wrong results — and they come up more often than you&#39;d expect. \u003Ccode>Object.hasOwn()\u003C\u002Fcode> is the ES2022 fix.\u003C\u002Fp>",{"id":97,"html":98,"text":99,"type":100,"level":31},"b4","How \u003Ccode>hasOwnProperty\u003C\u002Fcode> can go wrong","How hasOwnProperty can go wrong","heading",{"id":102,"html":103,"type":86},"b5","\u003Cp>\u003Cstrong>Case 1: null-prototype objects.\u003C\u002Fstrong> Objects created with \u003Ccode>Object.create(null)\u003C\u002Fcode> have no prototype. That&#39;s actually why people reach for them — as pure dictionaries where no inherited key can ever accidentally collide with a user-supplied key. The catch: they don&#39;t inherit \u003Ccode>hasOwnProperty\u003C\u002Fcode> either.\u003C\u002Fp>",{"id":105,"code":106,"type":90,"language":91,"highlight":107},"b6","const dict = Object.create(null);\ndict.name = \"parsa\";\n\ndict.hasOwnProperty(\"name\"); \u002F\u002F ❌ TypeError: dict.hasOwnProperty is not a function",[],{"id":109,"html":110,"type":86},"b7","\u003Cp>This pattern is common in parsers, caches, and config objects. When you encounter one and call \u003Ccode>.hasOwnProperty()\u003C\u002Fcode> on it, you get a runtime error, not a boolean.\u003C\u002Fp>",{"id":112,"html":113,"type":86},"b8","\u003Cp>\u003Cstrong>Case 2: shadowed method.\u003C\u002Fstrong> Because \u003Ccode>hasOwnProperty\u003C\u002Fcode> is inherited from \u003Ccode>Object.prototype\u003C\u002Fcode>, any object can define its own \u003Ccode>hasOwnProperty\u003C\u002Fcode> property that overrides the inherited one. This is rarely malicious but it does happen with deserialized data or objects built from untrusted input:\u003C\u002Fp>",{"id":115,"code":116,"type":90,"language":91,"highlight":117},"b9","const untrusted = {\n  hasOwnProperty: () => true, \u002F\u002F overrides the prototype method\n  name: \"parsa\",\n};\n\nuntrusted.hasOwnProperty(\"admin\"); \u002F\u002F ❌ true — completely wrong",[],{"id":119,"html":120,"type":86},"b10","\u003Cp>The inherited method is gone, replaced by a local property that returns whatever it wants.\u003C\u002Fp>",{"id":122,"html":123,"text":123,"type":100,"level":31},"b11","The pre-ES2022 workaround",{"id":125,"html":126,"type":86},"b12","\u003Cp>The fix that predates \u003Ccode>Object.hasOwn()\u003C\u002Fcode> is verbose but correct:\u003C\u002Fp>",{"id":128,"code":129,"type":90,"language":91,"highlight":130},"b13","Object.prototype.hasOwnProperty.call(obj, key);",[],{"id":132,"html":133,"type":86},"b14","\u003Cp>This goes directly to \u003Ccode>Object.prototype\u003C\u002Fcode> for the real method, then calls it with \u003Ccode>obj\u003C\u002Fcode> as the receiver. It handles null-prototype objects (the method comes from the prototype explicitly, not from the object) and it can&#39;t be shadowed (you&#39;re not reading the method from the object at all).\u003C\u002Fp>",{"id":135,"html":136,"type":86},"b15","\u003Cp>This is also what ESLint&#39;s \u003Ccode>no-prototype-builtins\u003C\u002Fcode> rule has been pushing you toward since 2016. If you&#39;ve seen that rule flag \u003Ccode>obj.hasOwnProperty(key)\u003C\u002Fcode> in a project and wondered why — this is the reason.\u003C\u002Fp>",{"id":138,"html":139,"type":86},"b16","\u003Cp>The problem is that \u003Ccode>Object.prototype.hasOwnProperty.call(obj, key)\u003C\u002Fcode> is 39 characters and easy to get wrong. It&#39;s the kind of code you copy-paste without fully understanding, which is exactly when bugs hide.\u003C\u002Fp>",{"id":141,"html":142,"text":143,"type":100,"level":31},"b17","\u003Ccode>Object.hasOwn()\u003C\u002Fcode> — the clean version","Object.hasOwn() — the clean version",{"id":145,"code":146,"type":90,"language":91,"highlight":147},"b18","Object.hasOwn(obj, key);",[],{"id":149,"html":150,"type":86},"b19","\u003Cp>Same semantics as \u003Ccode>Object.prototype.hasOwnProperty.call(obj, key)\u003C\u002Fcode>, but readable at a glance.\u003C\u002Fp>",{"id":152,"code":153,"type":90,"language":91,"highlight":154},"b20","const dict = Object.create(null);\ndict.name = \"parsa\";\n\nObject.hasOwn(dict, \"name\");    \u002F\u002F ✅ true\nObject.hasOwn(dict, \"admin\");   \u002F\u002F ✅ false\n\nconst untrusted = {\n  hasOwnProperty: () => true,\n  name: \"parsa\",\n};\n\nObject.hasOwn(untrusted, \"admin\"); \u002F\u002F ✅ false — can't be shadowed\nObject.hasOwn(untrusted, \"name\");  \u002F\u002F ✅ true",[],{"id":156,"html":157,"type":86},"b21","\u003Cp>Because \u003Ccode>Object.hasOwn\u003C\u002Fcode> is a static method on \u003Ccode>Object\u003C\u002Fcode> itself, there&#39;s nothing on the object being checked that can interfere with it.\u003C\u002Fp>",{"id":159,"html":160,"text":160,"type":100,"level":31},"b22","Where this comes up in real code",{"id":162,"html":163,"type":86},"b23","\u003Cp>The most common place you&#39;ll find this pattern is in loops over object keys:\u003C\u002Fp>",{"id":165,"code":166,"type":90,"language":91,"highlight":167},"b24","for (const key in someObject) {\n  if (Object.hasOwn(someObject, key)) {\n    \u002F\u002F skip inherited keys\n  }\n}",[],{"id":169,"html":170,"type":86},"b25","\u003Cp>The \u003Ccode>for...in\u003C\u002Fcode> loop walks the entire prototype chain. When you only care about own properties, you need to filter. \u003Ccode>Object.hasOwn()\u003C\u002Fcode> is the right tool.\u003C\u002Fp>",{"id":172,"html":173,"type":86},"b26","\u003Cp>It also turns up in validation logic, where you&#39;re checking that a required field actually exists on an incoming payload rather than on the payload&#39;s prototype:\u003C\u002Fp>",{"id":175,"code":176,"type":90,"language":91,"highlight":177},"b27","function validate(payload) {\n  const required = [\"id\", \"name\", \"email\"];\n  const missing = required.filter(field => !Object.hasOwn(payload, field));\n  if (missing.length) throw new Error(`Missing: ${missing.join(\", \")}`);\n}",[],{"id":179,"html":180,"type":86},"b28","\u003Cp>And in generic utility functions that need to handle arbitrary objects, including null-prototype ones:\u003C\u002Fp>",{"id":182,"code":183,"type":90,"language":91,"highlight":184},"b29","function pick(obj, keys) {\n  return Object.fromEntries(\n    keys\n      .filter(k => Object.hasOwn(obj, k))\n      .map(k => [k, obj[k]])\n  );\n}",[],{"id":186,"html":187,"text":187,"type":100,"level":31},"b30","TypeScript note",{"id":189,"html":190,"type":86},"b31","\u003Cp>TypeScript accepts \u003Ccode>Object.hasOwn()\u003C\u002Fcode> and narrows the type in the same contexts where \u003Ccode>in\u003C\u002Fcode> narrows:\u003C\u002Fp>",{"id":192,"code":193,"type":90,"language":194,"highlight":195},"b32","function process(config: unknown) {\n  if (typeof config === \"object\" && config !== null && Object.hasOwn(config, \"timeout\")) {\n    \u002F\u002F TypeScript knows config has a \"timeout\" property here\n    console.log((config as { timeout: number }).timeout);\n  }\n}","ts",[],{"id":197,"html":198,"type":86},"b33","\u003Cp>It doesn&#39;t give you automatic narrowing of the property&#39;s type (that&#39;s a separate constraint), but it does narrow the object to non-null.\u003C\u002Fp>",{"id":200,"html":201,"text":201,"type":100,"level":31},"b34","Browser support",{"id":203,"html":204,"type":86},"b35","\u003Cp>\u003Ccode>Object.hasOwn()\u003C\u002Fcode> is \u003Cstrong>Baseline 2022\u003C\u002Fstrong>: Chrome 93, Firefox 92, Safari 15.4, Node.js 16.9. It&#39;s been in every major runtime for nearly four years. There&#39;s no polyfill concern for greenfield projects, and even the \u003Ccode>Object.prototype.hasOwnProperty.call()\u003C\u002Fcode> workaround works identically in older environments if you need it.\u003C\u002Fp>",{"id":206,"html":207,"type":86},"b36","\u003Cp>ESLint&#39;s \u003Ccode>no-prototype-builtins\u003C\u002Fcode> rule (enabled by \u003Ccode>eslint:recommended\u003C\u002Fcode>) will flag any direct \u003Ccode>.hasOwnProperty()\u003C\u002Fcode> call on an object and suggest exactly this migration.\u003C\u002Fp>",{"id":209,"html":210,"type":86},"b37","\u003C!-- playground:start -->",{"id":212,"html":213,"text":213,"type":100,"level":31},"b38","🎮 Try it yourself",{"id":215,"html":216,"type":86},"b39","\u003Cp>\u003Cstrong>\u003Ca href=\"https:\u002F\u002Fdaily-post-dev.netlify.app\u002Fposts\u002F2026-08-06-object-hasown-safe-property-check\u002Fplayground\u002F\">▶️ Open the interactive playground →\u003C\u002Fa>\u003C\u002Fstrong>\u003C\u002Fp>",{"id":218,"html":219,"type":86},"b40","\u003Cp>\u003Cem>Runs right in your browser — poke at it and watch the concept react live.\u003C\u002Fem>\u003C\u002Fp>",{"id":221,"html":222,"type":86},"b41","\u003C!-- playground:end -->",{"id":224,"html":225,"type":86},"b42","\u003C!-- quiz:start -->",{"id":227,"html":228,"text":228,"type":100,"level":31},"b43","🧠 Test yourself",{"id":230,"html":231,"type":86},"b44","\u003Cp>Think it clicked? \u003Cstrong>\u003Ca href=\"https:\u002F\u002Fdaily-post-dev.netlify.app\u002Fquiz\u002Ftake.html?post=2026-08-06-object-hasown-safe-property-check\">Take the 8-question quiz →\u003C\u002Fa>\u003C\u002Fstrong>\u003C\u002Fp>",{"id":233,"html":234,"type":86},"b45","\u003Cp>\u003Cem>Instant feedback, a hint on every question, and an explanation for each answer — right or wrong.\u003C\u002Fem>\u003C\u002Fp>",{"id":236,"html":237,"type":86},"b46","\u003C!-- quiz:end -->",{"id":239,"html":240,"text":240,"type":100,"level":31},"b47","The takeaway",{"id":242,"html":243,"type":86},"b48","\u003Cp>Search your codebase for \u003Ccode>.hasOwnProperty(\u003C\u002Fcode>. Every match is a candidate for \u003Ccode>Object.hasOwn()\u003C\u002Fcode>. The swap is mechanical — \u003Ccode>obj.hasOwnProperty(key)\u003C\u002Fcode> becomes \u003Ccode>Object.hasOwn(obj, key)\u003C\u002Fcode> — but the result is immune to the two silent failure modes that the old pattern can&#39;t handle. If you&#39;re writing a library, a plugin system, or anything that accepts external objects as input, this is the version you want.\u003C\u002Fp>",{"id":245,"type":246},"b49","divider",{"id":248,"html":249,"type":86},"b50","\u003Cp>\u003Cem>Thanks for reading! Let&#39;s stay connected:\u003C\u002Fem>\u003C\u002Fp>",{"id":251,"type":252,"items":253,"ordered":18},"b51","list",[254,255,256,257,258],"⭐ \u003Cstrong>GitHub\u003C\u002Fstrong> — follow me and star the projects: \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fparsajiravand\">github.com\u002Fparsajiravand\u003C\u002Fa>","💬 \u003Cstrong>Discord\u003C\u002Fstrong> — join the frontend best-practices community: \u003Ca href=\"https:\u002F\u002Fdiscord.gg\u002Fd9KRhuAwQ\">discord.gg\u002Fd9KRhuAwQ\u003C\u002Fa>","📸 \u003Cstrong>Instagram\u003C\u002Fstrong> — frontend best practices, daily: \u003Ca href=\"https:\u002F\u002Fwww.instagram.com\u002Fbestpractice___\u002F\">@bestpractice___\u003C\u002Fa>","💼 \u003Cstrong>LinkedIn\u003C\u002Fstrong> — \u003Ca href=\"https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fparsa-jiravand\u002F\">linkedin.com\u002Fin\u002Fparsa-jiravand\u003C\u002Fa>","✉️ \u003Cstrong>Email\u003C\u002Fstrong> (work &amp; contract inquiries): \u003Ca href=\"mailto:bestpractice2026@gmail.com\">bestpractice2026@gmail.com\u003C\u002Fa>","Every JavaScript codebase has this pattern somewhere:\n\n```js\nif (obj.hasOwnProperty(key)) {\n  \u002F\u002F ...\n}\n```\n\nIt's idiomatic, it's readable, and most of the time it works. But there are two specific situations where it silently fails — one throws, one returns wrong results — and they come up more often than you'd expect. `Object.hasOwn()` is the ES2022 fix.\n\n## How `hasOwnProperty` can go wrong\n\n**Case 1: null-prototype objects.** Objects created with `Object.create(null)` have no prototype. That's actually why people reach for them — as pure dictionaries where no inherited key can ever accidentally collide with a user-supplied key. The catch: they don't inherit `hasOwnProperty` either.\n\n```js\nconst dict = Object.create(null);\ndict.name = \"parsa\";\n\ndict.hasOwnProperty(\"name\"); \u002F\u002F ❌ TypeError: dict.hasOwnProperty is not a function\n```\n\nThis pattern is common in parsers, caches, and config objects. When you encounter one and call `.hasOwnProperty()` on it, you get a runtime error, not a boolean.\n\n**Case 2: shadowed method.** Because `hasOwnProperty` is inherited from `Object.prototype`, any object can define its own `hasOwnProperty` property that overrides the inherited one. This is rarely malicious but it does happen with deserialized data or objects built from untrusted input:\n\n```js\nconst untrusted = {\n  hasOwnProperty: () => true, \u002F\u002F overrides the prototype method\n  name: \"parsa\",\n};\n\nuntrusted.hasOwnProperty(\"admin\"); \u002F\u002F ❌ true — completely wrong\n```\n\nThe inherited method is gone, replaced by a local property that returns whatever it wants.\n\n## The pre-ES2022 workaround\n\nThe fix that predates `Object.hasOwn()` is verbose but correct:\n\n```js\nObject.prototype.hasOwnProperty.call(obj, key);\n```\n\nThis goes directly to `Object.prototype` for the real method, then calls it with `obj` as the receiver. It handles null-prototype objects (the method comes from the prototype explicitly, not from the object) and it can't be shadowed (you're not reading the method from the object at all).\n\nThis is also what ESLint's `no-prototype-builtins` rule has been pushing you toward since 2016. If you've seen that rule flag `obj.hasOwnProperty(key)` in a project and wondered why — this is the reason.\n\nThe problem is that `Object.prototype.hasOwnProperty.call(obj, key)` is 39 characters and easy to get wrong. It's the kind of code you copy-paste without fully understanding, which is exactly when bugs hide.\n\n## `Object.hasOwn()` — the clean version\n\n```js\nObject.hasOwn(obj, key);\n```\n\nSame semantics as `Object.prototype.hasOwnProperty.call(obj, key)`, but readable at a glance.\n\n```js\nconst dict = Object.create(null);\ndict.name = \"parsa\";\n\nObject.hasOwn(dict, \"name\");    \u002F\u002F ✅ true\nObject.hasOwn(dict, \"admin\");   \u002F\u002F ✅ false\n\nconst untrusted = {\n  hasOwnProperty: () => true,\n  name: \"parsa\",\n};\n\nObject.hasOwn(untrusted, \"admin\"); \u002F\u002F ✅ false — can't be shadowed\nObject.hasOwn(untrusted, \"name\");  \u002F\u002F ✅ true\n```\n\nBecause `Object.hasOwn` is a static method on `Object` itself, there's nothing on the object being checked that can interfere with it.\n\n## Where this comes up in real code\n\nThe most common place you'll find this pattern is in loops over object keys:\n\n```js\nfor (const key in someObject) {\n  if (Object.hasOwn(someObject, key)) {\n    \u002F\u002F skip inherited keys\n  }\n}\n```\n\nThe `for...in` loop walks the entire prototype chain. When you only care about own properties, you need to filter. `Object.hasOwn()` is the right tool.\n\nIt also turns up in validation logic, where you're checking that a required field actually exists on an incoming payload rather than on the payload's prototype:\n\n```js\nfunction validate(payload) {\n  const required = [\"id\", \"name\", \"email\"];\n  const missing = required.filter(field => !Object.hasOwn(payload, field));\n  if (missing.length) throw new Error(`Missing: ${missing.join(\", \")}`);\n}\n```\n\nAnd in generic utility functions that need to handle arbitrary objects, including null-prototype ones:\n\n```js\nfunction pick(obj, keys) {\n  return Object.fromEntries(\n    keys\n      .filter(k => Object.hasOwn(obj, k))\n      .map(k => [k, obj[k]])\n  );\n}\n```\n\n## TypeScript note\n\nTypeScript accepts `Object.hasOwn()` and narrows the type in the same contexts where `in` narrows:\n\n```ts\nfunction process(config: unknown) {\n  if (typeof config === \"object\" && config !== null && Object.hasOwn(config, \"timeout\")) {\n    \u002F\u002F TypeScript knows config has a \"timeout\" property here\n    console.log((config as { timeout: number }).timeout);\n  }\n}\n```\n\nIt doesn't give you automatic narrowing of the property's type (that's a separate constraint), but it does narrow the object to non-null.\n\n## Browser support\n\n`Object.hasOwn()` is **Baseline 2022**: Chrome 93, Firefox 92, Safari 15.4, Node.js 16.9. It's been in every major runtime for nearly four years. There's no polyfill concern for greenfield projects, and even the `Object.prototype.hasOwnProperty.call()` workaround works identically in older environments if you need it.\n\nESLint's `no-prototype-builtins` rule (enabled by `eslint:recommended`) will flag any direct `.hasOwnProperty()` call on an object and suggest exactly this migration.\n\n\n\u003C!-- playground:start -->\n\n## 🎮 Try it yourself\n\n**[▶️ Open the interactive playground →](https:\u002F\u002Fdaily-post-dev.netlify.app\u002Fposts\u002F2026-08-06-object-hasown-safe-property-check\u002Fplayground\u002F)**\n\n_Runs right in your browser — poke at it and watch the concept react live._\n\n\u003C!-- playground:end -->\n\n\u003C!-- quiz:start -->\n\n## 🧠 Test yourself\n\nThink it clicked? **[Take the 8-question quiz →](https:\u002F\u002Fdaily-post-dev.netlify.app\u002Fquiz\u002Ftake.html?post=2026-08-06-object-hasown-safe-property-check)**\n\n_Instant feedback, a hint on every question, and an explanation for each answer — right or wrong._\n\n\u003C!-- quiz:end -->\n## The takeaway\n\nSearch your codebase for `.hasOwnProperty(`. Every match is a candidate for `Object.hasOwn()`. The swap is mechanical — `obj.hasOwnProperty(key)` becomes `Object.hasOwn(obj, key)` — but the result is immune to the two silent failure modes that the old pattern can't handle. If you're writing a library, a plugin system, or anything that accepts external objects as input, this is the version you want.\n\n---\n\n*Thanks for reading! Let's stay connected:*\n\n- ⭐ **GitHub** — follow me and star the projects: [github.com\u002Fparsajiravand](https:\u002F\u002Fgithub.com\u002Fparsajiravand)\n- 💬 **Discord** — join the frontend best-practices community: [discord.gg\u002Fd9KRhuAwQ](https:\u002F\u002Fdiscord.gg\u002Fd9KRhuAwQ)\n- 📸 **Instagram** — frontend best practices, daily: [@bestpractice___](https:\u002F\u002Fwww.instagram.com\u002Fbestpractice___\u002F)\n- 💼 **LinkedIn** — [linkedin.com\u002Fin\u002Fparsa-jiravand](https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fparsa-jiravand\u002F)\n- ✉️ **Email** (work & contract inquiries): [bestpractice2026@gmail.com](mailto:bestpractice2026@gmail.com)",{"title":261,"canonical":262,"description":263},"You use `obj.hasOwnProperty(key)` to check property ownership. It can ","https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fobject-hasown-safe-property-check","Two real cases where `obj.hasOwnProperty(key)` throws or returns wrong results — and why `Object.hasOwn(obj, key)` is the ES2022 fix that ESLint's `no-prototype-builtins` rule has ","019ff19b-f047-748a-800d-04d504fce9a0",{"id":266,"locked":18},"019ff19b-f06e-749b-b6e8-9b0d03f676b0",[268],{"id":33,"slug":34,"title":36,"_count":269},{"questions":39},[271],{"locale":13,"slug":34},{"id":33,"slug":34,"title":36,"_count":273,"questionCount":39},{"questions":39}]