Array.filter数组过滤:两段结构相似代码一正常一失效的原因排查
为什么示例1的Array.filter代码无法运行,而示例2可以?
这个问题的核心差异其实很简单——数据类型不匹配!咱们拆开两段代码仔细看:
先看示例1的问题根源
示例1里的yearOfProducing数组存储的是单个数值(比如2008、1998),通过map生成的dates数组中,每个元素的yearOfProducing属性也是单个数值:
// dates数组的实际结构: [ { model: 'toyota', yearOfProducing: 2008 }, { model: 'nissan', yearOfProducing: 1998 }, { model: 'chevy', yearOfProducing: 2018 }, { model: 'ford', yearOfProducing: 2013 } ]
你在filter里调用了yearOfProducing.includes(1998)——但数值类型(Number)根本没有includes方法!这个方法是数组(Array)特有的,所以运行这段代码会直接抛出TypeError: yearOfProducing.includes is not a function,导致代码完全无法执行。
另外还有个逻辑bug:就算includes能调用,单个数值也不可能同时等于1998和2018,用&&连接的条件永远为false,最终筛选结果也会是空数组。
再看示例2为什么能正常运行
示例2里的years数组存储的是数组类型(比如[2017, 2018]、[2017, 2018, 2019, 2020]),通过map生成的fruits数组中,每个元素的years属性都是数组:
// fruits数组的实际结构: [ { kind: 'mangosteen', years: [2017, 2018] }, { kind: 'durian', years: [2017, 2018, 2019, 2020] }, { kind: 'lychee', years: [2020] }, { kind: 'carambola', years: [2019, 2020] } ]
数组类型本身就有Array.prototype.includes方法,所以years.includes(2017) && years.includes(2018)是合法调用,能正确判断当前数组是否同时包含这两个年份,自然能正常执行。
示例1的修正方案
如果你的需求是筛选生产年份为1998或2018的车型,直接对数值进行判断即可,比如:
const cars = ['toyota', 'nissan', 'chevy', 'ford']; const yearOfProducing = [2008, 1998, 2018, 2013]; const dates = cars.map((model, index)=>({ model, yearOfProducing: yearOfProducing[index] })); // 修正后的filter逻辑:直接判断年份是否在目标集合中 const filteredCars = dates.filter(el => { const year = el.yearOfProducing; // 两种写法任选其一 return year === 1998 || year === 2018; // 或者用数组includes简化:[1998, 2018].includes(year) }); const filteredCars1 = filteredCars.map(el => el.model); console.log(filteredCars1); // 输出: ['nissan', 'chevy']
内容的提问来源于stack exchange,提问作者mosenzov




