← JavaScript Reflect.getOwnPropertyDescriptor():属性描述符的精准获取 没有下一篇了 →

JavaScript Reflect.getPrototypeOf():追溯对象的原型链

原创 2026-03-28 JavaScript 已有人查阅

掌握 Reflect.getPrototypeOf():追溯对象的原型链

在JavaScript中,原型链是一个绕不开的核心概念。每个对象都有一个内部链接指向它的原型,而这个原型又可能指向另一个原型,直到最终指向null。如何精准地获取一个对象的原型呢?Reflect.getPrototypeOf()就是为此而生的工具。

这个方法与Object.getPrototypeOf()的功能一致,但作为Reflect命名空间下的成员,它在元编程代理(Proxy)场景中扮演着更规范的角色。今天我们就来深入聊聊这个方法的用法、特性以及一些实战中的经验。

方法签名与参数说明

Reflect.getPrototypeOf(obj)
  • obj(目标对象):你想要获取其原型的对象。这个参数必须是对象,否则会抛出TypeError异常。

返回值

  • 返回指定对象的原型。如果对象没有原型(即通过Object.create(null)创建),则返回null

异常

  • 如果传入的参数不是对象(比如数字、字符串字面量、nullundefined),方抛出TypeError

为什么要用 Reflect.getPrototypeOf?

这个问题相信很多开发者都思考过。我的个人经验是,虽然Object.getPrototypeOf也能完成同样的事情,但当你开始使用Proxy进行高级编程时,Reflect的版本能提供更一致的函数式调用方式。

举个例子,当你为某个对象设置代理,并在getPrototypeOf中需要调用默认行为时,Reflect.getPrototypeOf(target)就是选择。它不会像Object.getPrototypeOf那样在某些情况下进行不必要的类型转换,行为更纯粹、更可预测。

核心要点:原型链的起点与终点

理解这个方法的关键在于明确原型链的概念。每个普通对象都有一个原型,而原型链的终点是nullReflect.getPrototypeOf()只返回对象的直接原型,而不是整个原型链。如果你想要追溯整个原型链,通常需要循环调用这个方法。

另外有一点需要特别注意:通过Object.create(null)创建的对象是一个“纯净”的对象,它没有任何原型,因此Reflect.getPrototypeOf()会返回null

本节课程知识要点

在开发中,如果你需要在不破坏封装性的前提下获取某个对象的原型,请优先使用Reflect.getPrototypeOf()。尤其是在编写与代理(Proxy)继承相关的底层库或框架时,这个方法能帮你避免很多隐式的类型转换带来的困扰。

实战示例:代码号学习编程之旅

下面我们通过几个贴近实际的示例来深入理解这个方法。这些示例都围绕一个“代码号学习平台”的用户和文章系统展开。

示例1:获取普通对象的原型

// 定义一个代码号学习平台的课程对象
const course = {
  title: 'JavaScript 原型链精讲',
  duration: 120
};

// 获取course对象的原型
const proto = Reflect.getPrototypeOf(course);
console.log(proto);
// 输出: {constructor: ƒ, __defineGetter__: ƒ, ...} (即 Object.prototype)

// 验证原型的原型
const protoOfProto = Reflect.getPrototypeOf(proto);
console.log(protoOfProto);
// 输出: null (Object.prototype的原型是null,这是原型链的终点)

示例2:处理没有原型的对象

// 创建一个空的对象,没有任何原型
const pureObject = Object.create(null);
pureObject.name = '纯净对象';
pureObject.type = '无原型';

// 获取这个对象的原型
console.log(Reflect.getPrototypeOf(pureObject));
// 输出: null

// 这个特性可以用来创建真正意义上的"字典"对象,避免原型链上的属性干扰
console.log('toString' in pureObject);
// 输出: false (因为没有原型链,所以没有继承任何Object的方法)

示例3:异常情况处理与类型检查

// 尝试在非对象上调用Reflect.getPrototypeOf
const invalidTargets = [123, 'hello', null, undefined];

invalidTargets.forEach(target => {
  try {
    Reflect.getPrototypeOf(target);
  } catch (error) {
    console.error(`目标 ${target} 不是对象,抛出: ${error.message}`);
  }
});

// 输出:
// 目标 123 不是对象,抛出: Reflect.getPrototypeOf called on non-object
// 目标 hello 不是对象,抛出: Reflect.getPrototypeOf called on non-object
// 目标 null 不是对象,抛出: Reflect.getPrototypeOf called on non-object
// 目标 undefined 不是对象,抛出: Reflect.getPrototypeOf called on non-object

// 个人经验分享:在调用这个方法之前,很好进行类型守卫
function safeGetPrototype(obj) {
  if (obj !== null && (typeof obj === 'object' || typeof obj === 'function')) {
    return Reflect.getPrototypeOf(obj);
  }
  console.warn('参数不是有效的对象,无法获取原型');
  return undefined;
}

safeGetPrototype(null); // 警告:参数不是有效的对象,无法获取原型

示例4:通过原型链判断对象类型

// 定义一个代码号学习平台的文章基类
function Article(title, author) {
  this.title = title;
  this.author = author || 'alan@ebingou.cn';
}

Article.prototype.getInfo = function() {
  return `${this.title} 作者: ${this.author}`;
};

// 创建文章实例
const jsArticle = new Article('Reflect API 实战', 'codeUser');

// 获取文章对象的原型
const articleProto = Reflect.getPrototypeOf(jsArticle);
console.log(articleProto === Article.prototype);
// 输出: true

// 获取原型的原型
const objectProto = Reflect.getPrototypeOf(articleProto);
console.log(objectProto === Object.prototype);
// 输出: true

// 原型链的终点
console.log(Reflect.getPrototypeOf(objectProto));
// 输出: null

// 这是一个实用技巧:通过连续调用Reflect.getPrototypeOf可以遍历整个原型链
let current = jsArticle;
let chain = [];
while (current !== null) {
  chain.push(current.constructor?.name || 'null');
  current = Reflect.getPrototypeOf(current);
}
console.log(chain);
// 输出: ['Article', 'Object', 'null']

示例5:函数对象的原型

// 函数也是对象,也有原型
function CodePlatform() {
  this.version = '2026';
}

// 获取函数对象的原型
const funcProto = Reflect.getPrototypeOf(CodePlatform);
console.log(funcProto === Function.prototype);
// 输出: true

// 获取Function.prototype的原型
console.log(Reflect.getPrototypeOf(Function.prototype));
// 输出: Object.prototype

// 最终原型链终点
console.log(Reflect.getPrototypeOf(Object.prototype));
// 输出: null

Reflect.getPrototypeOf()是理解JavaScript原型链的一把钥匙。它简洁、纯粹,不会进行任何额外的类型转换,是元编程场景下的可靠选择。记住,原型链的终点是null,而Object.create(null)可以创建真正“干净”的对象。在2026年的今天,掌握这些底层API,能让你在面对复杂的对象关系和继承体系时更加从容。

← JavaScript Reflect.getOwnPropertyDescriptor():属性描述符的精准获取 没有下一篇了 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号