instanceof 检查对象原型链是否包含构造函数的 prototype,不适用于原始值、跨 iframe 场景或被篡改原型的对象;更稳妥的替代方案是 object.prototype.tostring.call()。

instanceof 判断的是原型链关系,不是“类型”
JavaScript 没有传统意义上的“类型”,instanceof 实际检查的是左边对象的原型链上是否存在右边构造函数的 prototype。这意味着它无法识别原始值(如 string、number),也不能可靠区分内置对象的字面量写法和构造函数写法。
常见错误现象:new String('hello') instanceof String 返回 true,但 'hello' instanceof String 是 false;[] instanceof Array 为 true,但在跨 iframe 场景下可能失效。
- 只对对象(包括数组、正则、日期等)有效,对
null、undefined、字符串字面量等一律返回false - 依赖构造函数的
prototype属性未被篡改;若手动重写过Foo.prototype = {}且没补constructor,可能误判 - 跨执行上下文(如 iframe)时,
Array不是同一个构造函数,arr instanceof Array可能为false
替代 instanceof 的更稳方案:Object.prototype.toString.call()
当需要准确识别内置对象种类(尤其是跨 iframe 或防范原型污染时),优先用 Object.prototype.toString.call(x)。它返回形如 "[object Array]" 的字符串,不受原型链或执行上下文影响。
使用场景:工具函数中统一判断输入是否为数组、正则、Map、Set、Date 等;服务端渲染(SSR)中避免客户端/服务端构造函数不一致问题。
示例:
Object.prototype.toString.call([]) // "[object Array]" Object.prototype.toString.call(/abc/) // "[object RegExp]" Object.prototype.toString.call(new Date) // "[object Date]" Object.prototype.toString.call(null) // "[object Null]" Object.prototype.toString.call(undefined) // "[object Undefined]"
- 对所有值都安全,包括原始值和
null/undefined - 需注意返回字符串带空格和方括号,建议封装成工具函数并严格比对完整字符串
- 不能识别自定义类(除非显式修改
Symbol.toStringTag)
自定义类怎么让 instanceof 正常工作?
ES6 class 语法下,instanceof 默认可用,但要注意继承链和静态方法干扰。关键点在于确保子类的 prototype 正确链接到父类 prototype,且未被意外覆盖。
容易踩的坑:用 Object.assign(Sub.prototype, ...) 会抹掉 constructor 和原型链;直接赋值 Sub.prototype = {...} 会切断 __proto__ 链接。
- 继承必须用
extends关键字,或手动设置Sub.prototype.__proto__ = Super.prototype - 若重写
prototype,务必同时设置Sub.prototype.constructor = Sub - 避免在构造函数中返回对象字面量(如
return {a: 1}),这会让instanceof失效
什么时候不该用 instanceof?
当目标是判断“行为”而非“构造来源”时,instanceof 往往不是最佳选择。比如检查一个对象是否可迭代,应优先用 typeof obj[Symbol.iterator] === 'function';判断是否为 Promise,则用 obj && typeof obj.then === 'function'。
性能影响很小,但语义偏差大:它把“是不是这个类造出来的”当成“有没有这个能力”,而 JavaScript 中鸭子类型才是主流。
- 接口兼容性检查(如是否有
.map方法)——用属性检测,不用instanceof Array - 第三方库对象(如 React Element、Vue VNode)——它们通常不暴露构造函数,或故意隐藏
- TypeScript 编译后的代码中,
instanceof可能因类型擦除变得不可靠
真正复杂的地方不在语法,而在你到底想确认什么:是“它从哪儿来”,还是“它能干什么”。选错标准,后面所有判断都会偏。










