JS中array.map()及自定义forEach函数为何返回undefined?
findNeedle函数返回undefined? 这是个非常常见的JavaScript数组迭代误区,我来给你一步步拆解问题:
1. forEach回调里的return根本没让外层函数返回值
你看到console.log('needle')执行了,说明确实找到了目标元素,但这里的return 'needle'只作用于当前的forEach回调函数——它的作用仅仅是终止这一次的迭代(跳过当前元素后续的回调代码),并不会把值传递给外层的findNeedle函数。
而且forEach方法本身的返回值就是undefined,不管你在回调里return什么,forEach都不会帮你把这个值返回给外层函数。再加上你的findNeedle函数本身没有任何顶层的return语句,所以它最后会默认返回undefined。
2. 用map也会遇到同样问题的原因
map的设计目的是遍历数组,对每个元素执行回调后返回一个新数组,它不会在找到目标元素时停止遍历,也不会直接返回那个匹配的元素。哪怕你在map的回调里return 'needle',最后得到的是一个包含对应值的数组,而不是单个的'needle';再加上你的外层函数依然没有return这个结果,所以还是会得到undefined。
3. 正确的解决方案
方案1:用Array.find()(最推荐)
find方法就是专门为这类场景设计的——它会遍历数组,找到第一个满足条件的元素后立即返回该元素,并且停止遍历:
function findNeedle(array) { return array.find(element => element === 'needle'); } const needle = findNeedle(['hay', 'junk', 'hay', 'hay', 'moreJunk', 'needle', 'randomJunk']) console.log(needle) // 输出 'needle'
方案2:如果一定要用forEach
你需要在外层声明一个变量存储结果,找到元素后赋值,最后让外层函数return这个变量:
function findNeedle(array) { let target; array.forEach(element => { if(element === 'needle') { console.log('needle'); target = 'needle'; // 这里的return只是跳过当前迭代,forEach没法直接中断整个循环 return; } }); // 外层函数必须明确return结果 return target; }
注意:这种方法不如find高效,因为forEach会遍历完整个数组(哪怕找到元素后,后面的元素还是会被迭代)。
方案3:用普通for循环
最直观的方式,找到元素后直接return外层函数:
function findNeedle(array) { for(let i = 0; i < array.length; i++) { if(array[i] === 'needle') { console.log('needle'); return 'needle'; } } }
核心总结
你混淆了回调函数的return和外层函数的return的作用范围:回调里的return只影响当前回调的执行,不会让外层函数返回值。想要让findNeedle返回目标值,必须在函数顶层明确写出return语句,返回你想要的结果。
内容的提问来源于stack exchange,提问作者shane_00

