一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

JavaScript 异步函数在原型链上属性访问的细节

时间:2026-06-18 09:56:57 编辑:袖梨 来源:一聚教程网

async函数仍是Function实例,原型链与同步函数一致;其调用返回Promise实例,属性访问发生在Promise.prototype上,而非async函数自身。

异步函数本身是普通函数,它在原型链上的属性访问行为和同步函数完全一致——不因async关键字改变原型结构或查找逻辑。关键在于:**async 函数返回的是 Promise 实例,而 Promise 实例的原型链才是实际参与属性访问的对象**。

async 函数本身仍继承自 Function.prototype

声明一个 async 函数:

async function fetchUser() { return { id: 1 }; }

它本质仍是 Function 的实例:

  • fetchUser instanceof Functiontrue
  • fetchUser.__proto__ === Function.prototypetrue
  • 因此可正常访问 Function.prototype.callbindtoString 等方法

async 函数调用后返回的 Promise 才进入真正的属性查找链

执行 const p = fetchUser() 后,p 是 Promise 实例,其原型链为:

立即学习“Java免费学习笔记(深入)”;

  • p.__proto__ === Promise.prototype
  • Promise.prototype.__proto__ === Object.prototype
  • Object.prototype.__proto__ === null(链终点)

所以当你写 p.then(...)p.catch(...),是在 Promise.prototype 上查找方法,与原始 async 函数体无关。

注意:不能在 Promise 实例上直接访问 async 函数原型添加的自定义属性

例如:

async function say() {}say.custom = 'hello';const p = say();console.log(p.custom); // undefined

原因很清晰:

  • say.custom 是挂在函数对象自身的属性,不是其 prototype 上的
  • p 是 Promise 实例,与 say 函数对象无原型关联
  • 原型链只沿 __proto__ 向上查,不会跨对象查找“父级函数”的自有属性

想让异步结果携带额外行为?得靠 Promise 原型扩展或包装

若需统一增强所有 Promise 实例的能力(如加 .log() 方法),应修改 Promise.prototype

Promise.prototype.log = function() {  return this.then(res => {    console.log('Resolved:', res);    return res;  });};// 使用fetchUser().log(); // ✅ 可行

但要注意:不建议污染原生原型;更稳妥的方式是封装工具函数或使用类继承 Promise(需重写 constructor 并正确设置原型链)。

热门栏目