object.getprototypeof在ie8及更早版本完全不支持,部分android浏览器行为异常;安全polyfill需检测原生支持、避免__proto__、用constructor.prototype或tostring硬编码fallback,并显式处理null/非对象输入。

Object.getPrototypeOf 在 IE9+ 中已原生支持,但 IE8 及更早版本完全不支持,且部分 Android 2.x/4.x 浏览器存在返回 undefined 或抛错等非标准行为。它本身是只读操作,不修改原型链,因此比 Object.setPrototypeOf 更安全、更易 polyfill。关键不是“模拟”,而是提供一个在无原生支持时仍能正确返回对象直接原型的 fallback 实现。
确认是否真需 polyfill
多数现代项目已放弃 IE8 支持,但若明确需兼容 IE6–8 或某些定制嵌入式 WebView(如旧版 QtWebEngine、Trident 内核),才需手动补全。注意:
- IE6–8 不支持
Object.getPrototypeOf,也**不支持__proto__**(该属性在 IE10 才引入,且已被标准弃用) - 唯一可靠途径是利用
constructor.prototype配合类型判断,但该方式对 Object.create(null)、内置对象(如 Date、RegExp)或跨 iframe 创建的对象会失效 - 不能依赖
obj.constructor—— 它可被篡改,且 null/undefined/原始值无 constructor
安全、轻量的 polyfill 写法
以下代码仅在原生方法缺失时定义,不覆盖已有实现,也不污染全局,并显式处理边界情况:
if (typeof Object.getPrototypeOf !== 'function') {
Object.getPrototypeOf = function(obj) {
if (obj === null || typeof obj !== 'object') {
throw new TypeError('Object.getPrototypeOf called on non-object');
}
// IE6–8:尝试通过 constructor 推断(仅限普通对象)
if (obj.constructor && obj.constructor.prototype) {
return obj.constructor.prototype;
}
// fallback:使用 Object.prototype.toString 判断内置类型并硬编码返回
var toString = Object.prototype.toString;
switch (toString.call(obj)) {
case '[object Array]': return Array.prototype;
case '[object Function]': return Function.prototype;
case '[object Date]': return Date.prototype;
case '[object RegExp]': return RegExp.prototype;
case '[object Error]': return Error.prototype;
default: return Object.prototype;
}
};
}
Babel 与构建流程中的协同处理
该 polyfill 属于运行时逻辑,Babel 默认不会自动注入——因为它不是语法特性,而是 API 补丁。需主动引入:
- 在项目入口文件(如
main.js或index.js)顶部立即执行,早于任何依赖它的代码 - 避免用
@babel/preset-env的useBuiltIns: 'usage'自动注入 —— 它不识别Object.getPrototypeOf,该 API 未被 core-js 3 覆盖(core-js 主要聚焦于新增 API,而非修复老 API 缺失) - 若用 Webpack,可将其封装为独立模块,通过
ProvidePlugin全局注入,确保所有模块都能访问
替代思路:避免依赖 getPrototypeOf
在极老旧环境开发中,更推荐从设计上规避对 Object.getPrototypeOf 的强依赖:
- 用
instanceof或isPrototypeOf()替代部分判断场景(如Array.prototype.isPrototypeOf(arr)) - 对自定义类,显式缓存原型引用:
const MyProto = MyConstructor.prototype;,后续直接使用 - 用
Object.prototype.toString.call(x)做类型识别,比查原型链更稳定、兼容性更好











