前端阅读 335月28日 03:36
some、every、find、filter、map、forEach 有什么区别?
这 6 个方法是 JavaScript 数组最常用的迭代方法,面试几乎必考。核心区别在于返回值类型和是否短路,按返回值分三类记忆最清晰。一、遍历类(无返回值)forEach纯遍历,对每个元素执行回调,返回值永远是 undefined。不能中断:return 只跳过当前回调,break 语法不支持,想中途退出只能用 try/catch 抛异常(不推荐)不支持异步:回调里写 async/await 不会等待 Promise,因为 forEach 不关心返回值const list = [1, 2, 3];list.forEach(item => console.log(item)); // 1, 2, 3// return 只跳过当次,不会中断循环二、返回新数组map每个元素经回调映射后返回等长新数组,不改变原数组。const nums = [1, 2, 3];const doubled = nums.map(n => n * 2); // [2, 4, 6]filter返回满足条件的元素组成的新数组,长度可能小于原数组,不改变原数组。const nums = [1, 2, 3, 4, 5];const big = nums.filter(n => n > 3); // [4, 5]三、返回布尔值或单个元素find返回第一个满足条件的元素,找到即停止遍历(短路)。找不到返回 undefined。const users = [{id: 1, name: 'A'}, {id: 2, name: 'B'}];users.find(u => u.id === 2); // {id: 2, name: 'B'}some有任意一个满足条件就返回 true,找到即短路。全不满足返回 false。空数组返回 false。[1, 2, 3].some(n => n > 2); // true[1, 2, 3].some(n => n > 5); // false[].some(n => n > 0); // falseevery所有元素都满足条件才返回 true,遇到不满足即短路。空数组返回 true(空真逻辑 vacuous truth)。[1, 2, 3].every(n => n > 0); // true[1, 2, 3].every(n => n > 1); // false[].every(n => n > 0); // true(空真)四、对比速查表| 方法 | 返回值 | 是否短路 | 空数组返回 | 链式调用 | 修改原数组 ||------|--------|----------|-----------|---------|-----------|| forEach | undefined | 否 | undefined | 否 | 否 || map | 新数组 | 否 | [] | 是 | 否 || filter | 新数组 | 否 | [] | 是 | 否 || find | 单个元素/undefined | 是 | undefined | 否 | 否 || some | boolean | 是 | false | 否 | 否 || every | boolean | 是 | true | 否 | 否 |五、高频追问map 和 forEach 怎么选?需要返回新数组用 map,纯副作用(如 console.log、DOM 操作)用 forEach。关键区别:map 可链式调用,forEach 返回 undefined 不可链式。some 和 includes 有什么区别?includes(val) 判断数组是否包含某个具体值,用严格相等(===)比较some(fn) 判断是否有元素满足自定义条件includes 只能判断值存在性,some 可以写任意判断逻辑[1, 2, 3].includes(2); // true[1, 2, 3].some(n => n > 2); // true[{a: 1}].includes({a: 1}); // false(引用不同)[{a: 1}].some(o => o.a === 1); // true这些方法支持异步回调吗?都不原生支持。forEach 里写 async/await 不会等待 Promise resolve。需要异步迭代用 for...of + await 或 Promise.all + map。// 错误:forEach 不会等待 asyncids.forEach(async id => { const data = await fetch(id); // 并发执行,不会依次等待});// 正确方式1:for...offor (const id of ids) { const data = await fetch(id);}// 正确方式2:Promise.all + map(并行)const results = await Promise.all(ids.map(id => fetch(id)));find 和 filter 怎么选?只需第一个匹配用 find(性能更好,短路),需要所有匹配用 filter。reduce 为什么没列进来?reduce 是这 6 个方法的基础——map、filter、some、every、find 都可以用 reduce 实现。面试中常追问 reduce 的用法,但 reduce 更偏向"累加器"模式,功能更强大也更复杂,属于另一个考点的范畴。