最可靠的方式是使用 Object.prototype.toString.call(fn) === '[object AsyncFunction]',因其严格遵循ES规范且跨环境兼容;其他方法如 typeof、instanceof、constructor.name 或 toString().includes('async') 均存在误判风险。

JavaScript 中判断一个变量是否为 AsyncFunction(异步函数),不能仅靠 typeof 或 instanceof Function,因为异步函数本质上仍是函数,typeof asyncFn === 'function' 为 true,但无法区分普通函数和异步函数。
使用 Object.prototype.toString.call()
这是最可靠、跨环境兼容的方式。ES 规范规定,异步函数的内部 [[Class]] 标签为 "AsyncFunction",可通过 toString 方法暴露:
-
Object.prototype.toString.call(async function() {})返回"[object AsyncFunction]" - 普通函数返回
"[object Function]" - 箭头函数、生成器函数等也各自有对应标签(如
"[object GeneratorFunction]")
封装成工具函数示例:
function isAsyncFunction(fn) {return Object.prototype.toString.call(fn) === '[object AsyncFunction]';
}
✅ 支持所有合规引擎(Chrome、Firefox、Safari、Node.js 等),包括严格模式和模块环境。
立即学习“Java免费学习笔记(深入)”;
检查 fn.constructor.name(辅助判断,不推荐单独使用)
异步函数的构造器名通常是 "AsyncFunction":
foo.constructor.name === 'AsyncFunction' // true
⚠️ 注意:该方式有局限性 —— 构造器名可被篡改(如 fn.constructor.name = 'Foo'),且在某些打包或混淆环境下可能被修改或丢失;另外,通过 eval('async function() {}') 创建的函数也可能表现不一致。
因此,仅建议作为 toString.call 的补充验证,不可替代。
避免误判的常见陷阱
以下方式 ❌ 不能准确识别 AsyncFunction:
-
typeof fn === 'function':所有函数都满足,包括同步、异步、生成器、箭头函数 -
fn instanceof Function:同样无法区分类型 -
fn.toString().includes('async'):不可靠 —— 函数体可能含字符串"async",或被压缩/转译后丢失关键字 -
fn.constructor === AsyncFunction:全局AsyncFunction在某些沙箱或 iframe 中可能不可访问,且非标准全局属性,兼容性差
实际使用建议
生产环境中应优先采用 Object.prototype.toString.call() 方案。若需同时检测多种函数类型(如异步函数、生成器函数、普通函数),可统一用此方法匹配不同标签:
if (type === 'AsyncFunction') { ... }
简洁、安全、无副作用,且不依赖运行时环境是否暴露 AsyncFunction 构造器。


















