object.hasown在数组上严格检测自身数字索引属性,不查原型链,能正确识别稀疏数组空位,且不受原型污染和hasownproperty被覆盖的影响,比in和hasownproperty更安全可靠。

Object.hasOwn 在数组上判断索引属性时,行为与 in 操作符一致,但与 hasOwnProperty 不同——它能正确识别数组的数字索引是否为该数组自身的可枚举属性,包括稀疏数组中的“空位”。
只检测自身属性,不查原型链
数组的 length、push 等属性在原型上,Object.hasOwn(arr, 'length') 返回 false;而索引如 '0'、'2' 若真实存在于数组实例上(即被赋过值),则返回 true。
例如:
const arr = ['a', , 'c']; // 索引 1 是 empty slot console.log(Object.hasOwn(arr, '0')); // true console.log(Object.hasOwn(arr, '1')); // false ← 即使是稀疏位,也没该属性 console.log(Object.hasOwn(arr, '2')); // true console.log(Object.hasOwn(arr, 'length')); // false
比 in 操作符更安全,避开原型污染风险
in 会检查整个原型链,如果数组原型被意外添加了数字属性(如 Array.prototype[5] = 'hacked'),5 in arr 会误报为 true;而 Object.hasOwn(arr, '5') 始终只看 arr 自身,不受干扰。
推荐在需要严格判断“这个索引是不是当前数组自己拥有的属性”时优先使用 Object.hasOwn。
注意:字符串形式的索引是必须的
数组索引本质是字符串键(即使写成 arr[0],内部仍按 '0' 处理)。所以 Object.hasOwn(arr, 0) 会被自动转为字符串 '0',没问题;但若传入非规范索引(如负数、小数、空字符串),结果可能不符合直觉:
-
Object.hasOwn(arr, -1)→ 检查'-1',一般为 false -
Object.hasOwn(arr, 1.5)→ 检查'1.5',不是合法数组索引,通常为 false -
Object.hasOwn(arr, '')→ 检查空字符串键,除非手动设置过arr[''] = ...,否则为 false
对比 hasOwnProperty 的关键区别
arr.hasOwnProperty('0') 在绝大多数场景下效果相同,但存在一个边界问题:如果数组实例上**显式覆盖了 hasOwnProperty 方法**(比如 arr.hasOwnProperty = () => true),就会失效;而 Object.hasOwn 是静态方法,完全不受实例状态影响,更可靠。
因此,MDN 明确建议用 Object.hasOwn 替代 hasOwnProperty,尤其在处理不可信数据或动态对象时。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











