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

递归中如何跟踪计数?为何数组可累计数字变量却失效?

递归统计嵌套对象key次数时,数字计数器失效但数组可行的原因

我是JavaScript新手,想要编写一个统计嵌套对象中特定key出现次数的函数。尝试将计数器作为函数参数初始化,但递归返回后计数器无法保留计数——递归时正确给计数器加1,但返回后新增的计数丢失。最终通过空数组解决了问题:先递归收集所有嵌套对象的key再统计数量。想请教:为何数组能跟踪累计,数字变量却不行?

无法正常工作的计数代码

const countKeysInObj = function(obj, key, count = 0) {
    for (let prop in obj) {
        if (prop === key) {
            console.log("counting");
            count += 1;
        }
        if (typeof obj[prop] === 'object') {
            console.log("recursing");
            countKeysInObj(obj[prop], key, count);
        }
    }
    return count;
}
var testobj = { 'e': { 'x': 'y' }, 't': { 'r': { 'e': 'r' }, 'p': { 'y': 'r' } }, 'y': 'e' };
console.log(countKeysInObj(testobj, "e")) // 返回1,预期为2

原因解析

核心是JavaScript中基本类型和引用类型的参数传递规则不同:

  • 数字属于基本类型,传递参数时是值拷贝——每次递归调用,都会把当前count的数值复制一份传给子函数,子函数里修改的只是这个副本,不会影响外层函数的count变量。你原代码里递归调用后没把返回值赋值回count,所以子函数的计数完全没被外层接收。
  • 数组属于引用类型,传递参数时是引用传递——传递的是数组在内存中的地址,不管多少层递归,操作的都是同一个数组对象,所以往数组里添加元素的修改会一直保留。

修复数字计数器的写法

只要在递归调用时,把返回的计数赋值回当前的count即可:

const countKeysInObj = function(obj, key, count = 0) {
    for (let prop in obj) {
        if (prop === key) {
            count += 1;
        }
        // 排除null,因为typeof null也会返回object
        if (typeof obj[prop] === 'object' && obj[prop] !== null) {
            // 把递归返回的计数累加回当前count
            count = countKeysInObj(obj[prop], key, count);
        }
    }
    return count;
}
var testobj = { 'e': { 'x': 'y' }, 't': { 'r': { 'e': 'r' }, 'p': { 'y': 'r' } }, 'y': 'e' };
console.log(countKeysInObj(testobj, "e")) // 返回2,符合预期

数组方式的逻辑

数组能工作是因为所有递归层操作的是同一个数组,收集完所有匹配的key后再取长度:

const countKeysInObj = function(obj, key) {
    const keys = [];
    const traverse = (obj) => {
        for (let prop in obj) {
            if (prop === key) keys.push(prop);
            if (typeof obj[prop] === 'object' && obj[prop] !== null) {
                traverse(obj[prop]);
            }
        }
    }
    traverse(obj);
    return keys.length;
}
var testobj = { 'e': { 'x': 'y' }, 't': { 'r': { 'e': 'r' }, 'p': { 'y': 'r' } }, 'y': 'e' };
console.log(countKeysInObj(testobj, "e")) // 返回2

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 08:50:46