object.hasown 是 es2022 推荐的静态方法,用于安全判断对象自身是否拥有某属性,不查原型链、不依赖原型、能处理 null/undefined,比 in 和 hasownproperty 更可靠健壮。

Object.hasOwn 是 ES2022 引入的推荐方式,用于安全判断对象自身是否拥有某属性(不查找原型链),比 in 操作符和 hasOwnProperty 更可靠,特别适合在属性合并逻辑中避免原型污染和误判。
为什么不用 in 或 hasOwnProperty?
in 会查找整个原型链,可能把继承来的属性当作自有属性;hasOwnProperty 是实例方法,若对象原型被篡改(如 Object.prototype.hasOwnProperty 被覆盖或对象自身定义了同名属性),就会失效或抛错。Object.hasOwn 是静态方法,直接绑定到 Object 上,不受原型干扰,语义清晰且健壮。
合并时只取源对象自身的可枚举属性
属性合并常用于配置合并、浅拷贝等场景。用 Object.hasOwn 配合 for...in 可精准筛选源对象“自己定义”的属性,跳过原型链上的干扰项:
- 遍历源对象时,用 for...in 获取所有可枚举属性键
- 对每个键调用 Object.hasOwn(source, key) 确认是自有属性
- 满足条件才赋值到目标对象,避免意外覆盖或继承属性混入
处理 null/undefined 源对象更安全
Object.hasOwn 内部会对第一个参数做 null/undefined 检查,不会报错(返回 false),而 hasOwnProperty 在 null/undefined 上直接抛 TypeError。因此在不确定源对象是否存在的合并逻辑中,Object.hasOwn 天然更鲁棒:
- 无需提前 guard:if (source && typeof source === 'object')
- 直接写 Object.hasOwn(source, key) 即可,安全返回 false
- 配合可选链(?.)或空值合并(??)能写出更简洁的合并逻辑
一个实用的浅合并函数示例
下面是一个基于 Object.hasOwn 的通用浅合并工具:
function merge(target, ...sources) {
for (const source of sources) {
if (source == null) continue;
for (const key in source) {
if (Object.hasOwn(source, key)) {
target[key] = source[key];
}
}
}
return target;
}
它能正确处理 Object.create(null) 创建的对象、被篡改原型的对象,以及部分为 null 的源参数,不依赖 hasOwnProperty 行为,也不受 for...in 枚举限制影响。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











