jstips 第 10 期:检查对象属性是否存在的正确姿势 —— `in` 操作符与 `hasOwnProperty` 深度对比
教程【免费下载链接】jstipsThis is about useful JS tips!项目地址https://gitcode.com/gh_mirrors/js/jstips点击查看免费下载导读在 JavaScript 日常开发中判断一个对象是否拥有某个属性是最高频的操作之一。本文以 jstips 仓库 Check if a property is in a Object第 10 期技巧为骨架系统讲解if (obj.prop)直接判断的陷阱、in操作符与Object.prototype.hasOwnProperty两种原生方案的本质差异关键在“检查深度”自身属性 vs 原型链继承属性并结合现代 ES2022 的Object.hasOwn给出兼顾安全与兼容的实战建议。读完你将能准确选择属性存在性检查方案避免原型链污染与隐式类型转换带来的隐蔽 Bug。一、最常见的做法if (myObject.name)为什么不够严谨原文档首先指出很多开发者判断属性是否存在时习惯这样写var myObject { name: tips_js }; if (myObject.name) { ... }这段代码在name属性存在且值为真值时能正常工作但它存在两个致命缺陷真值性truthy检查不等于存在性检查。if (myObject.name)实际做的是“myObject.name是否为真值”而不是“myObject上是否定义了name”。当属性的值恰好是、0、false、null、undefined或NaN这类假值falsy时即使属性真实存在条件也会判定为不成立。例如var o { count: 0 }; if (o.count) { ... }永远不会进入分支但count属性确实存在。无法区分“属性不存在”与“属性存在但值为假”。很多业务 Bug 正源于此默认值覆盖、条件渲染、配置项合并等场景中开发者需要精确区分这两种情况。因此原文档推荐使用两种原生方法in操作符与Object.hasOwnProperty。它们都来自Object原型链任何继承自Object的对象都可以直接调用。二、两种原生方案in操作符in操作符用于判断某个属性是否存在于对象自身或其原型链上语法为prop in object其中prop是字符串或 Symbol 类型的属性名object是需要检查的对象。如果属性存在于对象自身或沿原型链向上可达返回true否则返回false。var myObject { name: tips_js }; name in myObject; // true age in myObject; // false三、两种原生方案Object.prototype.hasOwnPropertyhasOwnProperty是Object.prototype上的方法它只检查属性是否为对象自身的直接属性own property完全不考虑原型链myObject.hasOwnProperty(name); // true注意它是原型链上的方法因此几乎所有对象除Object.create(null)创建的空原型对象外都能直接调用。如果对象是通过Object.create(null)创建的它没有任何原型方法直接调用obj.hasOwnProperty(...)会报错此时应改用Object.prototype.hasOwnProperty.call(obj, key)或 ES2022 的Object.hasOwn。四、核心差异检查深度不同原文档核心示例原文档用一个对比示例展示了两种方案的“深度”差异var myObject { name: tips_js }; myObject.hasOwnProperty(name); // true name in myObject; // true myObject.hasOwnProperty(valueOf); // false, valueOf 继承自原型链 valueOf in myObject; // true结论一目了然hasOwnProperty只在该属性是对象自身直接属性时返回truein操作符不区分属性是对象自身创建的还是从原型链继承来的只要链上能找到就返回true。valueOf、toString、constructor、hasOwnProperty本身等都属于Object.prototype上的继承属性所以valueOf in myObject为true而myObject.hasOwnProperty(valueOf)为false。构造函数的原型链示例原文档进一步用构造函数验证这一差异var myFunc function() { this.name tips_js; }; myFunc.prototype.age 10 days; var user new myFunc(); user.hasOwnProperty(name); // true user.hasOwnProperty(age); // false, 因为 age 来自原型链这里name是构造函数体内通过this.name ...创建的实例自有属性而age挂在myFunc.prototype上因此name in user; // true自身属性 age in user; // true原型链上可达 user.hasOwnProperty(age); // false不是自身属性这正是“检查深度不同”的完整含义in覆盖整条原型链hasOwnProperty只覆盖对象自身。五、实战误区与原型链“假阳性”理解上述差异后几个经典误区需要特别警惕for...in遍历与hasOwnProperty的经典搭配。for...in会遍历包括继承属性在内的所有可枚举属性因此老代码中常见if (obj.hasOwnProperty(key))过滤。仓库另一篇技巧 Hash maps without side effects 正是针对此问题使用Object.create(null)创建无原型对象遍历时便无需再做自身属性检查也彻底避免in/for...in被原型链污染的问题。属性名恰好覆盖原型方法。若对象自身定义了名为hasOwnProperty的属性例如数据中恰好有该 key直接调用obj.hasOwnProperty(key)会得到非函数而抛错这也是原生方法被“屏蔽”的经典坑。用in判断“安全存在”并不安全。in只回答“链上是否存在”不回答“是否属于你”在序列化、深拷贝、白名单过滤等场景若混入继承属性会导致数据污染。仓库 Picking and rejecting object properties 中的pick实现使用k in obj判断后取值正是因为pick业务上希望容忍原型链属性而reject实现改用Object.keys(obj)仅枚举自身可枚举属性两种工具对“深度”的不同取舍恰与本文主题互为印证。六、现代演进Object.hasOwn与更多替代方案针对hasOwnProperty被覆盖、以及Object.create(null)对象无该方法的问题ES2022 引入了静态方法Object.hasOwn(obj, prop)Object.hasOwn(myObject, name); // true Object.hasOwn(myObject, valueOf); // false它等价于Object.prototype.hasOwnProperty.call(obj, prop)且对Object.create(null)对象同样安全。此外还有几种常用方案Object.keys(obj)返回自身可枚举属性名数组可用includes判断缺点是不可枚举属性与 Symbol 属性不会出现。Object.getOwnPropertyNames(obj)返回自身所有字符串属性名含不可枚举不含 Symbol。Reflect.ownKeys(obj)返回自身所有属性键含不可枚举与 Symbol。选择建议需求推荐方案只关心对象自身属性含不可枚举ES2022 环境Object.hasOwn(obj, key)需要兼容 ES5/旧环境Object.prototype.hasOwnProperty.call(obj, key)需要沿原型链判断属性可达性key in obj需要“值存在且非假值”的业务判断if (obj[key])明确知道语义前提需要遍历自身可枚举属性Object.keys(obj)七、小结按语义选择检查方式回到原文档的核心结论判断属性是否存在不应依赖真值判断而应在“自身属性”与“原型链可达属性”两个语义之间做出明确选择——前者用hasOwnProperty/Object.hasOwn后者用in。原文档最后还建议读者参考社区关于“检查属性存在时的常见错误”的讨论见仓库对应 issue 记录。在 jstips 仓库中本文对应的中文翻译见 _posts/zh_CN/javascript/2016-01-10-check-if-a-property-is-in-a-object.md繁体版见 _posts/zh_TW/javascript/2016-01-10-check-if-a-property-is-in-a-object.md西班牙语版见 _posts/es_ES/javascript/2016-01-10-check-if-a-property-is-in-a-object.md可供对照阅读。相关延伸还可参考仓库 Advanced Properties属性描述符与 getter/setter、Why you should use Object.is() in equality comparison-in-equality-comparison.md)相等性比较与 Short circuit evaluation in JS短路求值它们共同构成 JavaScript 对象操作中“精确判断”的完整工具箱。赞分享教程【免费下载链接】jstipsThis is about useful JS tips!项目地址https://gitcode.com/gh_mirrors/js/jstips点击查看免费下载相关推荐Vuetify 无障碍a11y实践指南Activator 语义属性与键盘焦点管理Vuetify 无障碍a11y实践指南Activator 语义属性与键盘焦点管理 Web 无障碍Accessibility简称 a11y是一项包容性教程freeCodeCamp Basic JavaScript 挑战精讲用 hasOwnProperty() 检测对象的属性是否存在freeCodeCamp Basic JavaScript 挑战精讲用 hasOwnProperty 检测对象的属性是否存在 本文基于 freeCodeCam前端后端教育千古前端图文教程JavaScript 对象的高级操作——hasOwnProperty 属性检测与 Object.freeze 对象冻结千古前端图文教程JavaScript 对象的高级操作——hasOwnProperty 属性检测与 Object.freeze 对象冻结 本文是《04 Java文档教程前端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Google发布EmbeddingGemma 2:740M参数开放多模态嵌入模型

Google发布EmbeddingGemma 2:740M参数开放多模态嵌入模型

Google DeepMind 于 2026 年 10 月 6 日正式发布 EmbeddingGemma 2,这是继去年 EmbeddingGemma 之后的新一代开放嵌入模型。官方数据显示,初代 EmbeddingGemma 下载量已超过 2000 万次,被广泛用于端侧搜索与隐私优先的 RAG 流水线。Embedding…

2026/11/3 16:48:27 阅读更多 →
毕业论文致谢章节被AIGC系统大段标红的原因分析与真情实感重构

毕业论文致谢章节被AIGC系统大段标红的原因分析与真情实感重构

毕业论文致谢章节被AIGC系统大段标红的原因分析与真情实感重构在硕士与博士研究生毕业论文的全部章节中,“致谢(Acknowledgements)”通常被视为作者最能自由抒发情怀的个性化空间。三年乃至五六载的求学生涯漫长艰辛,从文献调研的…

2026/10/19 2:08:35 阅读更多 →
晋级答辩复盘,录音整理到重点提炼,这一套流程真的太省心了

晋级答辩复盘,录音整理到重点提炼,这一套流程真的太省心了

每年年中到年底,是各大公司职级晋升、岗位竞聘、内部评审的高峰期。作为一个在职场摸爬滚打十几年的“老油条”,我参与过不下百场答辩会,既当过答辩人,也做过评审组秘书。说实话,答辩过程中最让人头疼的,从…

2026/10/19 2:08:30 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/8 1:19:03 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/7 12:08:40 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/8 1:35:05 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/8 1:38:41 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/7 12:08:40 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/8 1:23:14 阅读更多 →

日新闻

周新闻

月新闻