reflect.has()是es6引入的标准化方法,用于检测对象(含原型链)是否拥有某属性,语义等价于in操作符,但更规范、可被proxy拦截,且对非对象参数抛typeerror。

基本用法:检查自有属性和原型链上的属性
Reflect.has(obj, key) 接收两个参数:目标对象和要检查的属性键(字符串或 Symbol)。它会沿着原型链查找,只要属性可被 in 操作符检测到,就返回 true。
- 对普通对象、数组、内置对象(如 Date)都适用
- 不区分自有属性还是继承属性(这点和 Object.prototype.hasOwnProperty() 不同)
- 如果目标不是对象(如 null、undefined、原始值),会抛出 TypeError
和 in 操作符的区别与选择
行为上几乎等价:'name' in obj 和 Reflect.has(obj, 'name') 结果一致。但 Reflect.has 更适合以下情况:
- 需要统一使用反射 API(比如配合 Proxy 或其他 Reflect 方法)
- 属性名是变量或动态生成的,避免模板字符串拼接或 eval 风险
- 在函数式编程风格中保持调用一致性(如作为高阶函数参数传入)
常见误用提醒
注意几个易错点:
- 不能检测不可枚举但存在的属性?——可以,Reflect.has 不关心枚举性,只看是否存在(可被 in 找到)
- 不能检测 getter/setter?——可以,只要有属性描述符(哪怕只有 get),就返回 true
- Symbol 属性也能检测:
Reflect.has(obj, Symbol('id')) - 对 undefined/null 报错,建议提前校验:
obj && typeof obj === 'object' && Reflect.has(obj, key)
对比 hasOwnProperty:何时该用哪个?
如果只想确认属性是否直接定义在对象自身上(不查原型链),应该用 obj.hasOwnProperty(key) 或 Object.hasOwn(obj, key)(推荐后者,更现代且不被原型污染影响)。
-
Reflect.has(obj, 'toString')→ true(继承自 Object.prototype) -
obj.hasOwnProperty('toString')→ false(非自有) -
Object.hasOwn(obj, 'toString')→ false(同上,更安全)











