obj.hasOwnProperty(propName) 返回 true 表示自有属性,false 表示不存在或为继承属性;必须使用它来精准区分自有与继承属性,避免 for...in 遍历原型链污染(如 toString、hasOwnProperty 自身等),推荐用 Object.prototype.hasOwnProperty.call(obj, key) 或 Object.hasOwn(obj, key) 安全调用。

直接用 obj.hasOwnProperty(propName) 判断:返回 true 就是自有属性,false 表示该属性不存在或来自原型链。
为什么必须用 hasOwnProperty?
因为常规遍历(比如 for...in)会把原型上的属性也列出来,比如 toString、valueOf、hasOwnProperty 自身,甚至你给 Object.prototype 添加的方法。这些不是对象“自己”的,混进去容易导致缓存污染、序列化异常或意外调用。
怎么安全地调用 hasOwnProperty?
避免对象自身重写了 hasOwnProperty 方法(虽然少见但存在风险),推荐两种写法:
-
Object.prototype.hasOwnProperty.call(obj, 'name')—— 最稳妥,绕过实例方法 -
Object.hasOwn(obj, 'name')—— ES2022 新增的静态方法,更简洁,但需注意兼容性(现代浏览器和 Node.js ≥16.9 支持)
实际过滤自有属性的写法
遍历对象时只处理自有属性,常见于数据清洗、缓存构造、深拷贝等场景:
const data = { id: 1, name: 'Alice' };
data.toString = () => 'custom'; // 模拟污染
const ownKeys = [];
for (const key in data) {
if (Object.prototype.hasOwnProperty.call(data, key)) {
ownKeys.push(key);
}
}
// 结果:['id', 'name'],不包括 toString
和 in 运算符的区别要记牢
'prop' in obj 查的是“能不能访问到”,不管自有还是继承;obj.hasOwnProperty('prop') 查的是“是不是它自己定义的”:
-
{}.hasOwnProperty('toString')→ false(继承的) -
'toString' in {}→ true(能访问到) -
{x: 1}.hasOwnProperty('x')→ true -
'x' in {x: 1}→ true


















