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

递归调用的函数中内部函数idGenerator是否每次调用都会重新定义?

关于递归函数内部idGenerator重复定义的问题解答

明确结论

是的,每次调用recursively_add_id(包括递归过程中的每一次调用)时,内部的idGenerator箭头函数都会被重新定义。

运行机制解释

在JavaScript中,函数每被调用一次,就会创建一个全新的执行上下文。函数内部通过let/const声明的变量(包括函数表达式),都会在这个新的执行上下文中完成初始化。

你的代码里,idGenerator是myself(即recursively_add_id)函数的局部变量,所以每一次触发myself调用——不管是外部首次调用,还是递归过程中调用自身——都会重新生成一个idGenerator箭头函数的实例。

开销与优化建议

你猜测的没错,这种重复创建的开销确实极小。现代JavaScript引擎(如Chrome的V8)对这类短生命周期的小型函数有成熟的优化策略,不会对性能造成可感知的影响。

不过如果想彻底避免重复创建,也可以把idGenerator移到递归函数外部,只初始化一次:

方案1:挂载到模块作为私有工具函数

MyModule._idGenerator = () => '_' + (Math.random() * 0x1000000000000000);
MyModule.recursively_add_id = function myself(arg) {
    if (arg === null)
        return;
    else if (Array.isArray(arg))
        arg.forEach(element => myself(element));
    else if (typeof arg === 'object') {
        for (let key in arg)
            myself(arg[key]);
        arg.id = MyModule._idGenerator();
    }
    else // number, string...
        return;
};

方案2:用闭包封装,避免污染模块命名空间

MyModule.recursively_add_id = (function() {
    // 只在闭包初始化时创建一次
    const idGenerator = () => '_' + (Math.random() * 0x1000000000000000);
    return function myself(arg) {
        if (arg === null)
            return;
        else if (Array.isArray(arg))
            arg.forEach(element => myself(element));
        else if (typeof arg === 'object') {
            for (let key in arg)
                myself(arg[key]);
            arg.id = idGenerator();
        }
        else // number, string...
            return;
    };
})();

内容的提问来源于stack exchange,提问作者Francesco Marchetti-Stasi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 03:51:06