object.getprototypeof() 本身是 o(1) 操作,但循环中反复调用会阻碍 jit 内联且需重复验证原型槽,实测十万次比直接读属性慢 5–10 倍以上,链越深性能损耗越大。

Object.getPrototypeOf() 本身已经极快——它不查找、不计算、不触发副作用,只是读取对象头中固定偏移的 [[Prototype]] 指针,属于 O(1) 内存寻址。所谓“优化”,不是让它更快,而是避免误用导致它失去这个优势。
别在循环里反复调用
虽然单次调用开销几乎为零,但在高频循环中重复执行会阻碍 JIT 编译器内联,且每次都要确认对象当前的原型槽值。实测十万次调用比直接读属性慢 5–10 倍以上,链越深越慢。
- ❌ 错误写法:
for (let i = 0; i - ✅ 正确做法:提前缓存,如
const proto = Object.getPrototypeOf(list[0]); for (...) { /* 复用 proto */ } - 若处理的是同类对象(同构造函数),直接用
Constructor.prototype更稳定、更轻量
优先用类型判断替代原型获取
很多场景下你真正需要的不是“原型对象”,而是“它是不是某类实例”或“有没有某个方法”。这时 getPrototypeOf 是绕远路。
- 判断类型:用
obj instanceof MyClass—— 引擎深度优化,无额外开销 - 检查构造器:用
obj.constructor === MyClass(注意确保未被篡改) - 检查方法存在:用
typeof obj.method === 'function',比沿原型链找快得多
需要遍历原型链时,手动跳转更可控
如果业务逻辑确实要沿链查找属性(比如模拟 hasOwnProperty 的反向检查),不要靠反复调用 getPrototypeOf 实现。
- 先缓存起始原型:
let proto = Object.getPrototypeOf(obj); - 再用
while (proto !== null)循环,并在每层用Object.prototype.hasOwnProperty.call(proto, key)检查 - 这样只做必要跳转,避免重复函数调用开销,也更容易被引擎预测和优化
避开非标准访问方式
obj.__proto__ 看似简洁,但它是一个非标准 accessor 属性,每次访问都触发 getter 函数,涉及类型检查、权限验证等额外逻辑;某些严格模式或旧环境还可能报错或降级。
- ✅ 始终使用
Object.getPrototypeOf(obj)或Reflect.getPrototypeOf(obj)—— 行为一致,标准、稳定、零抽象层 - ⚠️ 不要用
obj.constructor.prototype:需两次属性访问,constructor 可能被覆盖,prototype 可能不存在或指向错误对象
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











