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

严格模式下替换arguments.callee的兼容方案(支持至ES2019)

严格模式兼容重构方案

原代码依赖严格模式下被完全禁用的非标准API:arguments.callee、Function.caller,在开启'use strict'时会直接抛出TypeError。以下是兼容到ES2019的重构实现,完全对齐原有函数的行为,不依赖任何被禁用的特性。

核心实现思路:通过Error实例的栈追溯能力获取完整调用链,解析栈字符串提取对应层级的函数名,所有支持ES2019的运行环境(现代浏览器、Node.js 12+)均原生支持该特性。

重构后完整代码

'use strict';
const utils = {
    /**
     * 获取上两层调用方的函数名
     * @param {string} [string] 原接口遗留参数,无实际逻辑作用,仅做兼容
     * @param {string} [callerName] 原接口遗留参数,无实际逻辑作用,仅做兼容
     * @return {string}
     */
    caller: function (string, callerName) {
        const stackFrames = this._getStackFrames();
        // 栈帧偏移:0为内部栈解析方法、1为当前caller方法、2为直接调用方、3为目标上两层调用方
        const targetFrame = stackFrames[3];
        return targetFrame ? this._extractFunctionName(targetFrame) : '';
    },
    /**
     * 获取直接调用方的函数名
     * @return {string}
     */
    function_name: function () {
        const stackFrames = this._getStackFrames();
        // 栈帧偏移:0为内部栈解析方法、1为当前function_name方法、2为目标直接调用方
        const targetFrame = stackFrames[2];
        return targetFrame ? this._extractFunctionName(targetFrame) : '';
    },
    /**
     * 内部方法:获取当前调用栈帧列表
     * @returns {string[]}
     * @private
     */
    _getStackFrames: function () {
        const err = new Error();
        // 统一换行符拆分栈行,过滤错误首行和空行
        return err.stack
            .split(/\r?\n/)
            .filter(line => {
                const trimmed = line.trim();
                return trimmed.length > 0 && !trimmed.startsWith('Error');
            });
    },
    /**
     * 内部方法:从栈帧行提取函数名
     * @param {string} frameLine
     * @returns {string}
     * @private
     */
    _extractFunctionName: function (frameLine) {
        const trimmedLine = frameLine.trim();
        // 匹配标准栈格式:at 函数名 (位置信息)
        const namedFnMatch = trimmedLine.match(/^at\s+([^\s(]+)\s*\(/);
        if (namedFnMatch?.[1] && namedFnMatch[1] !== '<anonymous>') {
            return namedFnMatch[1];
        }
        // 匹配全局/顶层调用的无括号格式
        const globalMatch = trimmedLine.match(/^at\s+([^:\\/]+):\d+:\d+$/);
        if (globalMatch?.[1]) {
            return globalMatch[1];
        }
        return '';
    }
};

使用注意事项

  • 实现完全对齐原有逻辑行为:匿名函数、无名称绑定的箭头函数会返回空字符串,和旧代码表现一致
  • 内部辅助方法不要改写为箭头函数,否则会导致栈帧偏移计算错误
  • 代码经过压缩混淆时函数名会被编译工具替换为短标识,该表现和旧实现完全一致,属于编译阶段的正常现象
  • 兼容所有ES2019标准运行环境,严格模式下无任何报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:48:19