in 运算符检查对象自身及整个原型链中是否存在指定属性名,无论是否可枚举、是否为 undefined 或是否可访问;'prop' in obj 返回 true 表示属性名存在,不关心值或可访问性。

in 运算符会检查对象自身及其整个原型链上是否存在指定属性名(无论是否可枚举),只要属性存在就返回 true。
in 检查的是“属性名”,不是“属性值”
它只关心属性是否被定义,不关心值是什么、是否为 undefined 或是否可访问。即使属性值是 undefined,只要该属性名存在于对象或其原型链中,in 就返回 true。
-
'toString' in {}→true(继承自Object.prototype) -
'notExist' in {}→false -
let obj = { prop: undefined }; 'prop' in obj→true
遍历整个原型链,直到找到或到达 null
in 从当前对象开始查找属性名,如果没找到,自动向上查找其 [[Prototype]](即 __proto__ 指向的对象),依此类推,直到原型链末端(null)。
- 查找过程与
obj.property访问行为类似,但in不触发 getter,也不读取值 - 不会跳过不可枚举属性:比如
hasOwnProperty是不可枚举的,但'hasOwnProperty' in obj仍为true - ES6+ 中,Symbol 属性同样被检查:
let sym = Symbol('a'); let obj = {}; obj[sym] = 1; sym in obj→true
与 hasOwnProperty 的关键区别
obj.hasOwnProperty(prop) 只检查对象自身,不查原型链;而 prop in obj 查自身 + 整条原型链。
立即学习“Java免费学习笔记(深入)”;
-
'toString' in {}→true,但{}.hasOwnProperty('toString')→false - 若需排除继承属性,必须配合
hasOwnProperty使用 - 注意:
hasOwnProperty本身可能被覆盖,安全写法是Object.prototype.hasOwnProperty.call(obj, prop)
实际使用中的常见陷阱
容易误判“属性是否存在”的真实意图,尤其在判断配置项或数据字段时。
- 把
in当作“属性有有效值”的判断依据 → 错误('key' in obj无法区分{key: undefined}和未定义) - 在类数组对象或 Map/Set 上滥用 →
in对非对象类型会强制转对象,可能产生意外结果(如'length' in 'abc'→true) - 与
Object.keys()混淆:后者只返回自身可枚举属性,不包含原型链和不可枚举属性
in 回答的是“这个名字有没有被声明过”,而不是“这个值有没有意义”。


















