Angular中map内带可选链?的对象属性过滤功能失效如何解决
问题原因
- 可选链覆盖范围不全:现有代码的可选链仅作用到属性访问环节,后续调用
toLowerCase()、indexOf()方法时没有做安全判断。如果job.job_details为undefined,或者jobCity为undefined,就会触发undefined.toLowerCase()、undefined.indexOf()的非法调用,直接抛出TypeError,导致这两个新增过滤条件无法正常执行。 - 空值未做兜底处理:即便补全方法调用的可选链,属性不存在时整个表达式会返回
undefined,此时undefined !== -1的判断结果为true,会导致没有对应属性的岗位被错误命中过滤条件,逻辑不符合预期。 - 原有三个属性过滤正常是因为
job_company、companyName、location、jobTitle均为接口定义的必填属性,不会出现undefined的情况,调用方法不会报错。
解决方案
补全可选链覆盖范围,同时用空值合并运算符??对空场景做兜底,将不存在属性的判断结果统一转为false,避免报错和逻辑异常。同时可以提前将过滤字符串转小写,减少重复计算,优化性能。
修改后的完整代码如下:
this.filteredList$ = combineLatest(this.list$, this.filter$).pipe( map(([jobs, filterString]) => { // 提前统一转换过滤字符串为小写,避免重复计算 const lowerFilter = filterString.toLowerCase(); return jobs.filter(job => job.job_company.companyName.toLowerCase().indexOf(lowerFilter) !== -1 || job.jobTitle.toLowerCase().indexOf(lowerFilter) !== -1 || job.job_company.location.toLowerCase().indexOf(lowerFilter) !== -1 || // jobCountry为JobDetails下的必填属性,只要job_details存在就有值,无需额外加可选链 (job.job_details?.jobCountry.toLowerCase().indexOf(lowerFilter) ?? -1) !== -1 || // jobCity为可选属性,需要保留可选链 (job.job_details?.jobCity?.toLowerCase().indexOf(lowerFilter) ?? -1) !== -1 ) }), tap(filtered => { this.allJobs = filtered; this.jobsChunk = filtered.slice(0, 9); }) );
说明:如果实际业务中存在
job_details不为空但jobCountry为空的特殊场景,可以给jobCountry也加上可选链(写成job.job_details?.jobCountry?.toLowerCase),容错性更强。
内容的提问来源于stack exchange,提问作者Jennifer Lacaste
相关产品推荐
相关产品推荐

