背景
新加入的项目里,代码里封装了一个这样一个方法,估计是想更优雅的使用三元表达式吧
export function safeSetValueWithBoolean(flag: boolean, value?: any, value1?: any): any {
return flag ? value : value1;
}
因为我是后加入的,我开始在项目里开发时,项目里已经有很多代码在用这个方法了。我个人的习惯,对于非自建的项目,尽量用人家封装好的东西,尽量保持风格一致,以免带来混乱,毕竟人家一直在用的东西应该没什么问题,
经过
注意:所有代码基于项目代码简化
他们之前组件有这样一段代码
{safeSetValueWithBoolean(
type==='a',
<>
<Row>
<span>
数量
</span>
<span className="card-num">{data.total}</span>
</Row>
</>,
null
)}
到我开发时,要添加一种新的类型b,b类型时data传递的一定是数组,为了不修改他们原有代码,以及保持风格统一,我就在后面加上了这段代码
{safeSetValueWithBoolean(
type==='b',
<>
<div>{data.map((item) => <span key={item}>{item} </span>)}</div>
</>,
null
)}
我将type='b',data=(对应获取到b类型的数据)传递给组件验证,没问题,本来想要不要加个可选链来着(?.map),后来觉得已经保证b类型的data一定是数组了,没必要多此一举,就觉得完工了。
然后就被原开发同事告诉我他使用a类型时报错了。
Uncaught TypeError: Cannot read properties of null (reading 'map')
我实验了一下,果然是这样。一开始还没反应过来,想着a类型type==='b'就是false了,怎么会走map方法,然后才反应过来,这个封装方法,和直接用三元表达式还是不一样的,比如value和value1是表达式的情况下,使用封装方法,方法拿到的是两个表达式的值,而不是两个表达式本身,就是说无论真假两个表达式都是要执行的,这和三元表达式是不一样的
复盘
其实我要是直接用三元表达式不用封装方法,或者用可选链,就不会出问题了,那些知识都清楚,但就是因为个人开发习惯、思虑不周、不细心等,还是让问题出现了
总结
- 封装方法是为了更优雅的实现相同效果,效果的等价比优雅更重要,一定要验证好。
- 不依赖外部调整保证内部逻辑安全,避免出现改动a部分代码引发b部分报错 码上掘金,(和这次报错无关,是我突然想到如果有其他人动了b类型data获取方法造成某些情况不是数组,就会出现他改的代码不报错,而报错行显示是我的代码,所以哪怕我在外部保证了data是数组,我也应该加上可选链)
- 不要迷信项目里其他人一直在用的方法,要看看是否适用自己的情况
附
演示:前端踩坑记录(一)