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

JavaScript递归函数按值传递问题及零计数实现疑问

JavaScript的参数传递:只有按值传递,没有按引用传递

核心结论

JavaScript仅支持按值传递,不存在所谓的“按引用传递”。很多人混淆的“引用传递”其实是对引用类型的按值传递——传递的是引用的副本,而非原始引用本身。

结合你的代码分析

你遇到的问题,本质是对JS参数传递规则的误解:

  1. 第二个代码里,递归调用countZeroes(parseInt(num / 10))时没有传递更新后的count参数,这是直接导致结果错误的第一个问题;
  2. 即使你传递了count,因为count是Number类型(基本类型),传递的是值的副本——函数内部修改的是这个副本,不会影响外部的count变量。

正确的递归实现方式

方式1:利用递归返回值累加(推荐,无副作用)

不需要依赖外部变量或引用类型,直接通过递归的返回值计算结果:

const number = 3004;

const countZeroes = function(num) {
    // 递归终止条件:num为0时返回0
    if (num === 0) {
        return 0;
    }
    // 计算当前位是否为0,加上递归调用的结果
    const current = num % 10 === 0 ? 1 : 0;
    return current + countZeroes(Math.floor(num / 10));
}

const result = countZeroes(number);
console.log('the result ', result); // 输出2

方式2:用引用类型传递计数(不推荐,有副作用)

如果一定要通过传递的方式维护计数,可以把count放在一个对象(引用类型)里,传递对象的引用副本,修改对象的属性会影响外部:

const number = 3004;

const countZeroes = function(num, counter) {
    if (num === 0) {
        return;
    }
    if (num % 10 === 0) {
        counter.value += 1;
    }
    // 递归调用时必须传递counter参数
    countZeroes(Math.floor(num / 10), counter);
}

const counter = { value: 0 };
countZeroes(number, counter);
console.log('the result ', counter.value); // 输出2

再明确JS的参数传递规则

  • 对于基本类型(Number、String、Boolean、Null、Undefined、Symbol、BigInt):传递的是值的副本,函数内部修改参数不会影响外部变量;
  • 对于引用类型(Object、Array、Function等):传递的是引用的副本——你可以通过这个副本修改引用指向的对象内容,但不能修改原始引用本身(比如把参数重新赋值为另一个对象,不会影响外部的引用)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 16:24:20