instanceof 用于检查对象是否由指定构造函数创建,原理是沿原型链查找 constructor.prototype;对原始值、跨 iframe、原型篡改、null/undefined 失效;适合验证继承关系;识别内置类型推荐 object.prototype.tostring.call()。

instanceof 不是“判断类型”,而是检查对象是否由某个构造函数(或类)创建,核心逻辑是:沿着对象的原型链向上查找,看能否找到 Constructor.prototype。
它怎么工作?
执行 obj instanceof Foo 时,JavaScript 会:
- 获取
obj.__proto__(即它的隐式原型) - 逐级向上比对:是否等于
Foo.prototype - 直到找到匹配,或到达原型链顶端(
null)为止
只要中间某一级匹配,就返回 true;否则为 false。
哪些情况它会失效?
它不是万能的,这几个常见限制必须清楚:
- 对原始值一律返回
false:'abc' instanceof String→false(但new String('abc') instanceof String→true) - 跨 iframe 或不同全局环境时不可靠:
iframe.contentWindow.Array和主窗口的Array是两个不同构造函数,数组实例用主窗口的Array判断会得false - 若手动重写了原型(如
MyClass.prototype = {})且没补constructor或修复__proto__链,可能误判 - 无法识别
null和undefined(它们不是对象,调用会直接报错或返回false)
它适合用在哪儿?
适合明确需要确认“血统”或继承关系的场景:
- 插件系统中验证传入对象是否是预期类的实例(如
logger instanceof ConsoleLogger) - 处理多态逻辑时区分子类:
if (item instanceof Button) { ... } else if (item instanceof Input) { ... } - 自定义类继承体系中判断层级:
child instanceof Parent在正确设置原型链时返回true
更稳妥的替代方案
如果目标是**准确识别内置对象种类**(比如确定是不是数组、正则、日期),推荐用:
Object.prototype.toString.call(x)
- 返回统一格式字符串,如
"[object Array]"、"[object RegExp]"、"[object Null]" - 对原始值、
null、undefined都安全 - 不受跨 iframe 或原型篡改影响
- 建议封装成工具函数,严格比对完整字符串(注意空格和方括号)











