判断属性归属需区分自有与继承属性:hasOwnProperty()判自有属性;Object.getOwnPropertyNames()和getOwnPropertySymbols()查全部自有属性;in操作符查存在性(含继承);getOwnPropertyDescriptor()检属性描述符。

检查属性归属的关键是分清“自有属性”和“继承属性”,不能只看能不能访问到,而要看它到底存在哪儿。用错方法容易把原型上的方法当成实例自己的,或者漏掉不可枚举的内置属性。
用 hasOwnProperty() 判断是否为自有属性
这是最直接的方式,专门用来确认某个属性是不是对象自己拥有的,不查原型链。
- 返回 true 表示该属性在对象自身上定义,不是从原型继承来的
- 对数组、日期、正则等内置对象也有效
- 注意:它只检查可枚举属性,但绝大多数自有属性默认就是可枚举的
例如:
const obj = { x: 1 };
obj.__proto__.y = 2;
console.log(obj.hasOwnProperty('x')); // true
console.log(obj.hasOwnProperty('y')); // false(y 在原型上)
用 Object.getOwnPropertyNames() 和 Object.getOwnPropertySymbols() 查看全部自有属性
当需要知道对象自身有哪些属性(包括不可枚举的),就得绕过常规遍历,用更底层的方法。
- Object.getOwnPropertyNames() 返回所有自有属性名(含不可枚举的字符串键)
- Object.getOwnPropertySymbols() 返回所有自有 Symbol 属性
- 两者结合,才能拿到对象自身的完整属性清单
比如:Array.prototype.push 是不可枚举的,Object.keys([]) 看不到它,但 Object.getOwnPropertyNames(Array.prototype) 能列出来。
用 in 操作符判断属性是否存在(含继承)
key in obj 会沿着整个原型链查找,适合“这个属性能不能用”的场景,但不适合“它属于谁”。
- 返回 true 只说明属性可访问,不区分是自有还是继承
- 对 in 来说,obj.hasOwnProperty('toString') 是 false,但 'toString' in obj 是 true(来自 Object.prototype)
- 慎用于判断归属,更适合做存在性校验
用 Object.getOwnPropertyDescriptor() 检查属性细节
当你怀疑某个属性被特殊配置过(比如不可写、不可枚举、不可配置),就需要看它的属性描述符。
- 能明确看到 enumerable、writable、configurable 等状态
- 返回 undefined 表示该属性不在对象自身上(包括不可枚举的也不在)
- 配合 Object.getPrototypeOf() 可逐层检查原型链上的属性配置
例如:Object.getOwnPropertyDescriptor([], 'length') 会返回一个描述符,其中 enumerable: false,说明它是自有但不可枚举的。


















