TypeScript类私有属性能否使用构造函数参数?是否属于不良实践?
在类属性中直接使用构造函数参数初始化是否属于不良实践?
这种写法本身不属于不良实践,是JavaScript/TypeScript类语法的标准合法行为,逻辑上也完全自洽:类字段初始化器可以访问当前类构造函数的入参,执行时机是在父类构造函数执行完成后、当前类构造函数体内代码执行前,和你把初始化逻辑写在构造函数第一行的效果基本一致。
你写的示例代码存在几个明显的问题,会导致运行/编译报错:
- 类属性定义的名称是
_name,但method1中直接调用了name.convertTrials(),没有加this.前缀,也没有对应变量声明,会直接抛出引用错误,正确写法应该是this._name.convertTrials() - 类型标注不要用大写的
String,这是JS字符串包装对象的类型,日常业务开发应该始终用小写的string标注原始字符串类型 - 你的构造函数被标记为
private,意味着这个类不能在外部通过new Eng()实例化,只能在类内部提供静态方法创建实例,如果没有配套的静态工厂方法,这个类根本无法正常使用
这种写法适合的场景:
- 属性初始化逻辑非常简单,仅依赖构造函数入参,没有额外分支、错误处理逻辑,写在属性定义处可以让读代码的人一眼看到属性的初始值,不用翻构造函数找赋值逻辑
- 类内部依赖的固定实现不需要对外暴露、不需要在测试时做Mock替换
以下情况不建议这么写,最好把初始化逻辑移到构造函数中,或者做依赖注入:
- 初始化逻辑超过1行,包含参数校验、错误捕获、分支判断等复杂逻辑,写在属性定义处会严重影响可读性
- 属性初始化依赖其他实例属性/方法:类字段是按从上到下的顺序初始化的,如果引用了后面才定义的字段,会拿到
undefined导致逻辑错误 - 代码对可测试性要求高:直接在类内部硬编码
new Name()初始化依赖,会导致单元测试时无法替换Mock实现,没法隔离测试当前类的逻辑。这种情况更推荐把Name实例作为构造函数入参传入,由外部控制依赖的初始化。
修正后可运行的代码参考:
import { Name } from './Name' class Eng { private _name: Name; private constructor(time: string, course: string) { // 构造函数内初始化和直接写在属性定义处效果一致,可按需选择 this._name = new Name(time, course); } // 配套静态工厂方法,适配私有构造函数的场景 static create(time: string, course: string) { return new Eng(time, course); } method1(){ let results = this._name.convertTrials(); return results; } }
内容的提问来源于stack exchange,提问作者user17764746
相关产品推荐
相关产品推荐

