用 in 和 hasownproperty 组合判断最可靠:in 检查属性是否可访问(含原型链),hasownproperty 判断是否为自身属性;object.keys 不适合存在性判断,因其仅返回可枚举的自身属性。

直接用 in 和 hasOwnProperty 配合判断最可靠。
用 in 检查属性是否存在(含原型链)
in 运算符只关心“能不能访问到”,不管属性在哪一级:
-
'name' in obj→true:只要obj自身有,或它的原型、原型的原型……上有,就返回true -
'toString' in obj→true:几乎所有对象都继承自Object.prototype,所以toString总是存在
用 hasOwnProperty 判断是否为自身属性
obj.hasOwnProperty('key') 只认对象自己身上定义的属性,不查原型链:
-
obj.hasOwnProperty('name')→true:如果name是obj = { name: 'a' }这样直接写的 -
obj.hasOwnProperty('toString')→false:哪怕能调用obj.toString(),它也不属于obj自己 - 注意安全:若对象是
Object.create(null)创建的,它没有hasOwnProperty方法,得写成Object.prototype.hasOwnProperty.call(obj, 'key')
组合使用,明确属性来源
一个清晰的判断函数可以这样写:
function getPropertySource(obj, key) {
if (!(key in obj)) return '不存在';
if (obj.hasOwnProperty(key)) return '自身属性';
return '原型链属性';
}
例如:
const child = Object.create({ inherited: 1 }); child.own = 2;-
getPropertySource(child, 'own')→'自身属性' -
getPropertySource(child, 'inherited')→'原型链属性' -
getPropertySource(child, 'missing')→'不存在'
补充:Object.keys 不适合做存在性判断
Object.keys(obj).includes('key') 只能检查“可枚举的自身属性”,容易漏掉:
- 不可枚举属性(比如通过
Object.defineProperty设置的enumerable: false) - 虽然它是自身属性,但
Object.keys根本不会返回它 - 所以它不能替代
hasOwnProperty做“是否为自身属性”的判断











