存在性检查需先明确“存在”定义:查自有属性用Object.hasOwn(安全高效),查自有+继承属性用in操作符,避免obj.key !== undefined等误用,特殊结构用对应API如map.has()。

规范化的属性存在性检查,核心是明确“存在”的定义:你要查的是对象自身的属性,还是包括原型链上的?值为 undefined 的属性算不算“存在”?根据这个前提选方法,而不是凭直觉写 obj.key !== undefined。
查自有属性(推荐用 Object.hasOwn)
现代项目首选 Object.hasOwn(obj, 'key')。它语义清晰、不被原型污染、性能好,且已获主流环境支持(Node.js 16.9+、Chrome 93+、Firefox 92+、Safari 16.4+)。
- 比
obj.hasOwnProperty('key')更安全:无需担心对象自身覆盖了该方法 - 比
in更精准:只查自身,不查原型链 - 兼容旧环境时可加简单 polyfill:
Object.hasOwn ??= Object.prototype.hasOwnProperty.call
查自有 + 继承属性(用 in 操作符)
当逻辑依赖“能否通过点号或中括号访问到该属性”时(比如配置合并、兜底取值),'key' in obj 是最自然的选择。
- 语法简洁,无函数调用开销
- 涵盖所有可访问路径:自有属性、原型链属性、甚至
Object.prototype上的方法(如toString) - 注意:它不区分来源,也不过滤不可枚举属性——这正是它的设计意图
避免三种常见误用
这些写法看似简单,实则语义错位、易出 bug:
-
obj.key !== undefined:无法区分“属性不存在”和“属性存在但值为undefined”,还可能因obj为null或undefined报错 -
Object.keys(obj).includes('key'):漏掉不可枚举属性(如JSON.stringify用的toJSON),且每次调用都生成新数组,性能差 -
obj.hasOwnProperty('key'):若对象来自Object.create(null)或被篡改过原型,会直接报错;应优先用Object.hasOwn替代
特殊结构用专用方法
对非普通对象,按类型使用对应 API:
-
Map和WeakMap:用map.has(key) -
Set和WeakSet:用set.has(value) -
Array:查索引存在性用index >= 0 && index ,而非 <code>arr[index] !== undefined(稀疏数组会误判)


















