在函数内部修改入参是否为不良编程风格?TypeScript场景分析
两种TypeScript函数实现的优劣分析
首先明确:两种方案的核心差异不仅是“是否修改入参”,还涉及类型严谨性和数组引用/副本的处理逻辑,下面逐一拆解:
第一种方案的问题
你的代码逻辑在技术上是可行的(按值传递的入参重赋值确实不会影响调用方),但被批评的点主要集中在以下两点:
- 类型标注不严谨:入参标注为
TypeOfObject[],但代码里处理了!myArgument的情况,说明实际入参可能是undefined,正确的类型应该是TypeOfObject[] | undefined,否则TypeScript会在调用方传入undefined时报错,违背了TS的类型安全初衷。 - 违反“入参只读”的编程约定:在团队协作中,函数入参通常被视为“只读”的外部输入,修改入参变量会降低代码可读性——其他开发者阅读代码时,默认入参变量保持原始传入值,突然的重赋值会增加理解成本,也可能引发后续代码的逻辑混淆(比如后续误判入参是否为
undefined)。
第二种方案的特点
第二种方案解决了“修改入参”的问题,但也引入了新的特性和潜在问题:
- 明确区分原始入参和内部变量:通过新变量
myArgumentSecond隔离了外部输入和内部使用的值,符合“入参只读”的约定,可读性更好。 - 强制创建数组副本:
[...myArgument]会生成原数组的浅拷贝,这意味着如果后续代码修改数组元素,不会影响调用方的原始数组。但这一点是否有必要,取决于业务需求——如果你的函数不需要保护原数组不被修改,那么这个拷贝是多余的性能开销。 - 同样存在类型标注问题:入参同样应该标注为
TypeOfObject[] | undefined,否则TS会禁止传入undefined,和你的实际处理逻辑矛盾。
更优的替代方案
结合TS的特性,最简洁且符合规范的写法是使用默认参数或空值合并运算符:
// 若允许调用方不传入参数或传入undefined,直接用默认值 export const myFunction = (myArgument: TypeOfObject[] = []) => { // do something with myArgument } // 若明确允许入参为undefined(比如调用方可能主动传入) export const myFunction = (myArgument?: TypeOfObject[]) => { const processedArg = myArgument ?? []; // do something with processedArg }
这种写法既解决了入参可能为undefined的问题,又不需要修改入参或额外的条件判断,同时保持了类型严谨性。
结论
- 第一种方案并非技术错误,但类型不严谨且违反通用编程约定,不利于团队协作和代码维护。
- 第二种方案解决了入参修改的问题,但多余的数组拷贝可能是不必要的,需根据业务场景判断。
- 最优解是利用TS的默认参数或空值合并运算符,实现更简洁、安全的代码。
内容的提问来源于stack exchange,提问作者user1195883
相关产品推荐
相关产品推荐

