跨 iframe 的 prototype 彼此隔离,Object.prototype.toString.call() 是最可靠的跨环境类型判断方法,因其返回标准字符串如"[object Array]"且不受 frame 隔离影响。

在不同 iframe(或 window)之间,JavaScript 的原型对象是**彼此隔离、不共享**的。这意味着即使两个 frame 中都定义了 Array 或 Object,它们的 Array.prototype 和 Object.prototype 也是**不同的对象实例**,内存地址不同,=== 比较会返回 false。所以直接用 instanceof 或 isPrototypeOf() 跨 frame 判断,结果可能不符合预期。
为什么跨 frame 的 prototype 不相等
每个 iframe 拥有独立的全局执行环境,包括独立的内置构造函数和原型对象:
iframe1.contentWindow.Array !== iframe2.contentWindow.Arrayiframe1.contentWindow.Array.prototype !== iframe2.contentWindow.Array.prototype- 因此
arr instanceof iframe2.contentWindow.Array恒为false,哪怕arr是 iframe2 中创建的数组
如何安全判断跨 frame 对象的“类型语义”
不能依赖构造函数或原型引用相等,但可借助**可序列化、环境无关的特征**来识别类型:
-
用
Object.prototype.toString.call(obj):返回标准字符串如"[object Array]"、"[object Date]",该方法不受 frame 隔离影响,是跨环境最可靠的类型标识方式 -
检查对象行为而非身份:例如判断是否为类数组,可检查
typeof obj.length === 'number'且obj.hasOwnProperty('length'),再配合Symbol.iterator in obj等 -
手动桥接原型链(仅限可信同源场景):若 iframe 同源,可通过
postMessage传递类型信息,或在父页面中统一维护类型映射表,把子 frame 的对象“投影”到主环境上下文中做判断
避免踩坑的关键点
以下操作在跨 frame 场景下不可靠,应明确规避:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
立即学习“Java免费学习笔记(深入)”;
- 不用
obj.constructor === Array—— 构造函数来自不同 frame,引用不同 - 不用
Array.prototype.isPrototypeOf(obj)—— 原型对象不是同一个 - 不用
Object.getPrototypeOf(obj) === Array.prototype—— 同样因原型对象不等而失败 - 不依赖
__proto__或修改原型链来“对齐”—— 违反同源策略且不可控
实用建议:封装一个跨 frame 类型检测工具
可以这样写一个轻量函数:
function getCrossFrameType(obj) {
return Object.prototype.toString.call(obj).slice(8, -1); // 如返回 "Array", "Date", "RegExp"
}
// 使用示例(无论 obj 来自哪个 iframe)
const arr = iframe.contentWindow.JSON.parse('[1,2,3]');
console.log(getCrossFrameType(arr) === 'Array'); // true
这个方法稳定、无副作用,适用于所有标准内置类型,也兼容大多数 polyfill 行为。

















