二分查找:查找目标最近较小数返回undefined的bug排查
兄弟,我太懂这种调试到怀疑人生的感觉了——明明调试时变量输出都跟预期一样,结果函数愣是返回个undefined,尤其是你还怀疑问题出在开头,那大概率是这几个常见的坑:
1. 最容易踩的:函数末尾漏写return语句
这绝对是高频问题!比如你可能在循环里把closestSmaller变量更新得明明白白,但写完循环就直接结束函数了,忘了加return closestSmaller;。举个反例:
function findClosestSmaller(arr, target) { let closestSmaller; // 循环里正确更新了closestSmaller for (let num of arr) { if (num < target && (closestSmaller === undefined || num > closestSmaller)) { closestSmaller = num; } } // 这里漏了return!函数默认返回undefined }
哪怕循环里变量完全正确,没return的话函数就是会返回undefined,这锅真的得甩给“忘了写return”。
2. 开头初始值的边界逻辑漏洞
你的列表是有序递增的(比如示例里的[1,23,45,67,94,122]),如果开头的初始值设得不对,也可能导致意外返回undefined。比如:
function findClosestSmaller(arr, target) { let closestSmaller; // 初始为undefined // 倒序遍历找第一个小于target的数 for (let i = arr.length - 1; i >= 0; i--) { if (arr[i] < target) { closestSmaller = arr[i]; break; } } // 如果所有元素都大于等于target,closestSmaller还是undefined return closestSmaller; }
不过你说调试时变量输出符合预期,那这种情况概率低,但如果你的测试用例刚好是目标值比所有元素都大,那初始值没设的话也会返回undefined?不对,示例里目标值96,94是符合的,所以还是更可能是第一种情况。
3. 分支里的return漏了返回值
比如你在某个条件分支里写了return;(不带任何值),而不是return closestSmaller;:
function findClosestSmaller(arr, target) { let closestSmaller; for (let num of arr) { if (num >= target) { return; // 这里只写了return,没返回值! } closestSmaller = num; } return closestSmaller; }
如果遍历到第一个大于等于target的元素时触发这个return,函数就会直接返回undefined,哪怕之前已经找到了正确的closestSmaller。
快速验证方案
你可以在函数的最后一行先加个console.log('最终要返回的值:', closestSmaller);,然后再写return closestSmaller;。如果控制台能打印出正确的94,但函数还是返回undefined,那可能是调用函数的地方有问题?不过99%的概率是你漏写了return语句。
对了,针对有序列表,其实用二分查找能更快找到结果,不过先把当前的undefined问题解决再说~
内容的提问来源于stack exchange,提问作者Monique

