You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

已关闭严格模式仍报错:TypeScript提示无法访问函数的callee

问题描述

我习惯在调试、性能分析或熟悉代码时,在应用里随处插入自定义日志函数,用arguments.callee.name自动获取所在函数名,不用手动输入——只需要粘贴myProfilingFunc(arguments.callee.name);就行。这种方式在非严格模式的JavaScript里正常运行,但在TypeScript里却报错:

TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

就算在tsconfig.json里关闭了所有严格相关选项(包括strict、alwaysStrict设为false,noImplicitUseStrict设为true),问题还是存在。这个功能2019年还能用,现在突然失效了。最小复现代码如下:

function testCallee() {
    console.log(arguments.callee.name);
}

testCallee();
解决方案

为什么原来的方法失效了

即使关闭了TypeScript的严格编译选项,现代JavaScript运行环境(浏览器、Node.js等)可能默认对模块代码启用严格模式,而arguments.callee在严格模式下是被明确禁用的,所以不管编译选项怎么设,运行时都会报错。此外,TypeScript新版本的编译逻辑调整,也可能导致相关代码被自动纳入严格模式范围。

替代方案:通过Error栈追踪获取函数名

可以利用Error对象的栈信息来解析当前执行的函数名,不用依赖arguments.callee:

function getCurrentFunctionName(): string | undefined {
    const stack = new Error().stack;
    if (!stack) return undefined;
    // 解析栈帧,不同环境格式略有差异,这里取调用getCurrentFunctionName的上一层函数
    const frame = stack.split('\n')[1].trim();
    // 提取函数名,兼容不同浏览器/Node.js的栈格式
    const match = frame.match(/at\s+(?:(\w+)\s+\()|at\s+(\w+)/);
    return match ? (match[1] || match[2]) : undefined;
}

// 自定义日志函数
function myProfilingFunc() {
    const funcName = getCurrentFunctionName();
    console.log(`[Profiling] 当前函数:${funcName}`);
}

// 使用示例
function testFunc() {
    myProfilingFunc();
}

testFunc(); // 输出 [Profiling] 当前函数:testFunc

更简洁的写法(针对非箭头函数)

如果你的函数都是普通命名函数,也可以直接利用函数的name属性,不过需要手动传入函数本身:

function myProfilingFunc(func: Function) {
    console.log(`[Profiling] 当前函数:${func.name}`);
}

function testFunc() {
    myProfilingFunc(testFunc);
}

testFunc(); // 输出 [Profiling] 当前函数:testFunc

这种写法虽然需要手动写函数名,但比栈追踪性能更好,且兼容性更稳定。

TypeScript装饰器方案(适合类方法)

如果是类中的方法,可以用装饰器自动注入日志,完全不用手动写代码:

function Profiled(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    descriptor.value = function(...args: any[]) {
        console.log(`[Profiling] 调用方法:${propertyKey}`);
        return originalMethod.apply(this, args);
    };
    return descriptor;
}

class TestClass {
    @Profiled
    testMethod() {
        // 业务逻辑
    }
}

const instance = new TestClass();
instance.testMethod(); // 输出 [Profiling] 调用方法:testMethod

内容的提问来源于stack exchange,提问作者Chema

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 15:05:16