最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
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 Function→ true -
fetchUser.__proto__ === Function.prototype→ true - 因此可正常访问
Function.prototype.call、bind、toString等方法
async 函数调用后返回的 Promise 才进入真正的属性查找链
执行 const p = fetchUser() 后,p 是 Promise 实例,其原型链为:
立即学习“Java免费学习笔记(深入)”;
p.__proto__ === Promise.prototypePromise.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 并正确设置原型链)。