应使用 'prop' in obj 判断属性是否存在,再用 === 显式比较值;object.hasown(obj, 'prop') 更精确检测自有属性;避免 !obj.prop 混淆虚值语义。

直接用 obj.prop === false、obj.prop === null 或 obj.prop === undefined 会混淆“值为 false”、“值为 null”和“属性根本不存在”这三种情况。关键在于:属性是否存在,和属性值是什么,是两个独立问题。
用 in 操作符检测属性是否存在
它只关心对象(含原型链)上有没有这个键,不关心值是什么。
-
'prop' in obj→ true 表示属性存在(哪怕值是undefined、null或false) -
'prop' in obj→ false 表示属性确实没定义(既不在对象自身,也不在原型链上) - 例如:
let obj = { prop: false }; 'prop' in obj返回 true;let obj = {}; 'prop' in obj返回 false
用 hasOwnProperty 检测自有属性
比 in 更精确,排除原型链上的属性,只看对象自己声明的。
-
obj.hasOwnProperty('prop')→ true 表示该属性是对象自身的,不是从原型继承来的 - 适合需要严格区分“自己定义”和“继承而来”的场景
- 注意:ES6 后推荐用
Object.hasOwn(obj, 'prop'),更安全(能正确处理被重写的hasOwnProperty)
用 obj?.prop === undefined 区分“值为 undefined”和“属性不存在”
可选链(?.)让访问更安全,但要注意:如果属性存在且值就是 undefined,结果仍是 undefined;如果属性根本不存在,也是 undefined —— 这两者无法靠 ?. 单独区分。
- 先用
'prop' in obj判断是否存在 - 再用
obj.prop取值,结合=== false、=== null、=== undefined做具体判断 - 示例逻辑:
if (!('prop' in obj)) {
// 属性不存在} else if (obj.prop === false) {
// 属性存在,且值明确为 false} else if (obj.prop === null) {
// 属性存在,且值明确为 null} else if (obj.prop === undefined) {
// 属性存在,但值被设为 undefined(人为赋值)}
避免用 !obj.prop 做判断
它会把所有虚值(false、0、''、null、undefined、NaN、document.all)一并归为“假”,完全无法区分语义。
- 比如
obj.count = 0和obj.count = null,!obj.count都是 true,但含义截然不同 - 业务中常需区分“数量为 0”和“数量未设置”,这时必须显式检查类型或存在性











