查自有属性用object.hasown(obj,'key'),兼容旧版用object.prototype.hasownproperty.call(obj,'key');查原型链存在用'key' in obj;禁用obj.key!==undefined和object.keys(obj).includes('key')。

选哪种方案,取决于你真正想问的是什么——是“这个 key 能不能从对象上读到”,还是“这个属性是不是对象自己定义的”。不同问题对应不同答案,没有万能解法。
要查“对象本身有没有这个属性”(不看原型)
用 Object.hasOwn(obj, 'key') 最稳妥。它是 ES2022 标准方法,语义清晰、性能好、不怕原型被污染,现代环境(Node.js 16.9+、主流浏览器)都支持。如果需要兼容旧版,回退到 Object.prototype.hasOwnProperty.call(obj, 'key') 即可。
- 它能检测所有自有属性,不管是否可枚举(比如
Object.defineProperty(obj, 'x', { value: 1, enumerable: false })) - 比
obj.hasOwnProperty('key')更安全,避免对象自身覆盖了该方法 - 比
Object.keys(obj).includes('key')快得多,也不产生临时数组
要查“这个 key 在对象或它的原型链上是否存在”
直接用 'key' in obj。这是语法级操作符,引擎优化充分,语义就是“能否通过 obj.key 访问到”,适合兜底逻辑、配置合并、判断方法是否可用等场景。
- 它不关心属性值是什么,
undefined、null、0都不影响结果 - 会命中原型上的属性(如
'toString' in {}返回true) - 不可枚举属性也能被检测到
别用 obj.key !== undefined 判断存在性
这不是在检查“是否存在”,而是在检查“值是否不等于 undefined”。一旦属性真实存在但值就是 undefined,就会误判为“不存在”;更糟的是,如果 obj 是 null 或 undefined,这行代码直接抛错。
- 它还会触发 getter,带来副作用
- 语义错位:你问的是结构问题,却用值来回答
- 真要判断值,就该明确说“值是否已设置且非 undefined”
少用 Object.keys(obj).includes('key')
除非你**明确需要可枚举 + 自有**这两个条件同时满足,否则没必要绕这么大弯。它先生成全部可枚举键的数组,再遍历查找,既慢又占内存。
- 漏掉不可枚举属性(比如很多内置方法、
JSON.stringify依赖的toJSON) - 完全忽略原型链,连
'toString'都查不到 - 每次调用都新建数组,对高频操作不友好
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











