instanceof 的核心是检查 B.prototype 是否在 A 的原型链中,其底层依赖 Object.getPrototypeOf 安全获取每级原型并逐级比对,该方法是规范标准,替代非标准的 __proto__;跨 iframe 失效因不同全局环境的 prototype 对象不等。

Object.getPrototypeOf 与 instanceof 的核心关联在于:instanceof 的判断完全依赖于原型链的遍历,而 Object.getPrototypeOf 正是安全、标准地获取对象上一级原型的方法——它正是 instanceof 底层所用的关键机制之一。
instanceof 实际在做什么?
表达式 A instanceof B 并不是检查 A “是不是 B 创建的”,而是严格检查:
“B.prototype 这个对象,是否出现在 A 的原型链中”。
这个过程不涉及构造函数执行逻辑、不看 new 调用痕迹,只做一件事:沿着 A 的 [[Prototype]] 链向上找,看有没有一个节点恰好等于 B.prototype。
Object.getPrototypeOf 是怎么参与其中的?
ES 规范要求 instanceof 必须使用标准方式访问原型,不能依赖非标准的 __proto__。因此现代实现(包括 V8、SpiderMonkey)内部实际调用的是:
-
Object.getPrototypeOf(A)获取 A 的直接原型 - 再对其结果重复调用
Object.getPrototypeOf,直到返回 null - 每一步都比对当前原型是否 === B.prototype
这正是手写 myInstanceof 时推荐用 Object.getPrototypeOf 而非 __proto__ 的原因:前者是规范 API,后者是历史遗留属性,且在某些环境(如 strict 模式下某些对象)可能不可写或不可访问。
为什么跨 iframe 会失效?
因为不同全局环境(比如主页面和 iframe)各自拥有独立的 Array、Date 等构造函数。虽然它们名字一样,但:
iframe.contentWindow.Array !== Array- 所以
iframeArr.constructor.prototype !== Array.prototype - 导致
iframeArr instanceof Array返回 false
而 Object.getPrototypeOf(iframeArr) 返回的确实是 iframe 内的 Array.prototype,它和主页面的 Array.prototype 是两个完全不同的对象——instanceof 的严格引用比对自然失败。
可以替代 instanceof 的更可靠方式?
当需要跨环境兼容或规避原型篡改风险时,可考虑:
-
Object.prototype.toString.call(value):返回[object Array]类字符串,稳定且不受原型链影响 -
Array.isArray()、isMap()等专用方法:针对内置类型,语义明确、性能好、跨 iframe 安全 -
constructor.name或value.constructor === SomeClass:仅适用于同环境、未重写 constructor 的情况,慎用
这些方法不依赖原型链遍历,因而绕开了 Object.getPrototypeOf 和 instanceof 共有的边界限制。

















