object.getprototypeof 是跨沙箱环境下可靠识别内置类型的底层方法,因其比对原型对象本身而非构造函数引用,可规避 iframe 等独立全局环境导致的 instanceof 失效问题。

Object.getPrototypeOf 是 JavaScript 中获取对象原型(即其内部 [[Prototype]])的核心方法。在跨沙箱(如 iframe、Web Worker、或第三方脚本隔离环境)场景下,直接用 instanceof 或构造函数比对会失效——因为不同执行上下文中的内置构造函数(如 Array、Date)是彼此独立的引用。此时,借助 Object.getPrototypeOf 沿原型链向上追溯并比对原型对象本身,是一种更可靠、更底层的类型自检方式。
为什么跨沙箱时 instanceof 失效?
每个沙箱(如 iframe)拥有独立的全局环境,因此它的 Array 构造函数和主页面的 Array 不是同一个函数,即使都叫 Array。所以:
-
iframe.contentWindow.Array === window.Array返回false -
arr instanceof iframe.contentWindow.Array在主页面中无法成立,反之亦然 - 但所有标准数组的原型链顶端,最终都指向各自沙箱内的
Array.prototype,而这个原型对象在同沙箱内是唯一的
用 Object.getPrototypeOf 安全识别内置类型
不依赖构造函数名或实例化来源,而是通过原型对象的“身份”来判断。关键思路:先获取目标对象的原型,再与已知原型(来自同一沙箱)做严格相等比较。
- 检测是否为数组:
Object.getPrototypeOf(obj) === Array.prototype(仅限同沙箱) - 跨沙箱时,需在目标沙箱内执行该判断逻辑——例如把检测函数注入 iframe 并调用
- 更通用做法:在目标环境中取一个已知类型的基准原型,如
Object.getPrototypeOf([]),然后与待测对象的原型链逐级比对
构建可复用的跨沙箱类型检查器
核心策略是「在目标上下文中运行原型比对逻辑」。常见实现方式:
- 对 iframe:使用
iframe.contentWindow.eval或postMessage + 回调执行检测代码,并传回结果 - 对 Web Worker:通过
worker.postMessage发送数据,Worker 内用Object.getPrototypeOf判断后返回类型标识 - 封装工具函数示例:
function isCrossOriginArray(target, context) {<br> return context.eval('Object.getPrototypeOf(arguments[0]) === Array.prototype');<br> }
注意:需确保context是可信且可执行 eval 的环境;生产环境建议改用 postMessage 避免 eval 风险
注意事项与边界情况
该方法虽绕过构造函数隔离,但仍受原型链完整性影响:
- 若对象被篡改过
__proto__或用Object.setPrototypeOf修改原型,检测可能误判 - 原始值(如字符串字面量
"abc")无法直接调用Object.getPrototypeOf,需先装箱:Object.getPrototypeOf(new String("abc")) - 对于 null 和 undefined,
Object.getPrototypeOf会抛出 TypeError,需提前 guard - 某些 polyfill 或框架(如 Proxy 封装对象)可能拦截原型访问,导致行为异常











