JavaScript嵌套函数能否复用同名入参?3/5倍数求和返回0值调试
你遇到的返回结果恒为0的核心原因
两个版本的代码存在共通的逻辑疏漏,是直接导致结果异常的根源:
- 调用内层函数时没有传入任何实参:不管是第一版还是第二版,你写的调用语句都是
returnNumbers(),括号为空。这时候内层函数定义的形参会被赋值为undefined,当执行for循环的边界判断i < undefined时,条件永远不成立,循环体一次都不会执行,最终返回的收集倍数的数组永远是空数组。空数组执行reduce从0开始累加,自然最后结果就是0。 - 第一版代码存在变量名遮蔽的问题:内层
returnNumbers的形参也叫number,这个值会把外层solution作用域的同名入参完全遮蔽,哪怕外层的number传了正确值,内层只要没拿到传入的实参,根本读不到外层的数值。 - 冗余的判断逻辑可以简化:你写的多层if判断(先判断同时被3和5整除,再分别判断被3、被5整除)和单个判断
i % 3 === 0 || i % 5 === 0的逻辑完全等价,没有必要写多层分支。
第二版调整代码的问题
你尝试在外层定义临时变量x = number的操作本身没有语法错误,但完全没有必要:JS的作用域规则允许内层函数直接读取外层函数作用域的变量,不需要特意拷贝参数、也不需要修改内层函数的形参名。而且你这次调整依然没解决“调用内层函数没传参”的核心问题,自然还是得到0的结果。
可直接运行的修正版本
方案1 保留你原有嵌套传参的结构
只需要补上调用内层函数时的实参,再简化冗余判断,顺带加上题目要求的负数边界兜底:
function solution(number){ // 入参为负数时直接返回0,符合题目测试用例要求 if (number < 0) return 0; function returnNumbers(limit){ let numbers = []; for (let i = 1; i < limit; i++){ if (i % 3 == 0 || i % 5 == 0) numbers.push(i); } return numbers; } // 核心修正:调用时把外层的number作为实参传入内层函数 let sum = returnNumbers(number).reduce(function(a, b){ return a + b; }, 0); return sum; }
方案2 利用JS作用域特性简化代码
内层函数可以直接访问外层的number入参,不需要额外定义形参,调用时也不用传参,还能避免变量重名遮蔽的问题:
function solution(number){ if (number < 0) return 0; // 内层函数不需要定义形参,直接读取外层的number即可 function returnNumbers(){ let numbers = []; for (let i = 1; i < number; i++){ if (i % 3 == 0 || i % 5 == 0) numbers.push(i); } return numbers; } // 这时候空括号调用returnNumbers是正常的,它会自动从外层作用域取number的值 let sum = returnNumbers().reduce(function(a, b){ return a + b; }, 0); return sum; }
你原来写的遍历收集数字的逻辑本身没有问题,只是在跨函数传递边界值的步骤漏了实参,修正后即可正常运行。
内容的提问来源于stack exchange,提问作者Ryan Tucker
相关产品推荐
相关产品推荐

