in操作符能检测方法名是否存在于对象自身或原型链上,只看键是否存在、不关心值,且自动沿原型链查找;需结合object.hasown区分是否为自有属性。

in 操作符能直接判断一个方法名是否存在于对象自身或其原型链上,只要该方法作为属性被定义过(无论是否可枚举、是否为 undefined 值),它就返回 true。
它不看值,只看“键是否存在”,且自动沿原型链向上查找。
比如:
-
"toString" in {}→true(继承自Object.prototype) -
"push" in []→true(继承自Array.prototype) -
"map" in new Set()→false(Set实例没有map,Set.prototype也没有) -
"hasOwnProperty" in {}→true(Object.prototype.hasOwnProperty是继承来的)
关键点在于:方法在原型链上是作为函数对象挂载的属性,而 in 正是检测这个属性名是否存在。
如何确认某个方法来自原型链而非对象自身?
单靠 in 无法区分来源,需结合 hasOwnProperty 或 Object.hasOwn:
-
"toString" in {}→true -
{}.hasOwnProperty("toString")→false(不是自有属性) -
Object.hasOwn({}, "toString")→false(ES2022 推荐写法,更安全)
所以,典型组合用法是:
const obj = {};
if ("toString" in obj) {
console.log("方法存在");
if (!Object.hasOwn(obj, "toString")) {
console.log("但它是从原型链继承来的");
}
}
实际常用场景
检测浏览器 API 是否可用:
"fetch" in window、"ResizeObserver" in window、"AbortController" in window判断类实例是否具备某能力:
"addEventListener" in element(元素继承自EventTarget.prototype)"toISOString" in new Date()(继承自Date.prototype)-
避免调用前报错:
if ("customMethod" in instance) { instance.customMethod(); }
注意事项
in要求右侧必须是对象(不能是null或undefined):"x" in null→ 抛出TypeError
安全写法:obj != null && "x" in obj数组索引也适用(因为数组索引本质是字符串属性名):
0 in [1, 2]→true,"length" in []→true-
不可枚举属性也能被
in捕获:const obj = {}; Object.defineProperty(obj, "hidden", { value: 42, enumerable: false }); "hidden" in obj → true
不复杂但容易忽略:in 是唯一原生支持“原型链感知”的存在性检查方式,专为这类判断而生。











