如何重构构造函数中的super调用以解决'this'在super前使用的错误
如何重构构造函数中的super调用以解决'this'在super前使用的错误
这个问题的核心在于在TypeScript/JavaScript的子类构造函数中,必须先调用super()才能访问this——包括你的私有字段#env,因为它是实例的一部分,在super()完成父类初始化前,实例还没完全创建,自然无法访问。
我们可以通过两种常见方式来解决这个问题:
方案1:将依赖注入移到构造函数参数中(推荐)
Angular支持直接在构造函数参数中注入依赖,这样我们能在调用super()之前就拿到环境变量的值,完全避开this的问题:
import { Inject, Injectable } from '@angular/core'; import { ENVIRONMENT_TOKEN } from '@reg/environment/domain'; @Injectable({ providedIn: 'root' }) export class RegStore extends ImmutableStore<TRegState> { // 直接在构造函数参数中注入,同时声明为私有成员 constructor( @Inject(ENVIRONMENT_TOKEN) private readonly env: typeof ENVIRONMENT_TOKEN ) { super({ name: 'RegistrationStore', mutationProducerFn: produce as unknown as MutationFn<TRegistrationState>, initialState: new RegState(), plugins: [ // 直接使用参数中的env,不需要this ...env.signalStoryStorePlugins, useStorePersistence({ persistenceKey: 'RegStore', persistenceStorage: localStorage, }), ] }); } store: Immutable<TRegState> = this.state(); }
这种方式符合Angular的依赖注入最佳实践,同时完美解决了super()调用前无法访问this的限制。
方案2:先调用super,再动态添加插件(如果父类支持)
如果你的ImmutableStore类提供了动态添加插件的方法(比如addPlugins),可以先调用super()完成初始化,之后再添加环境相关的插件:
import { Injectable } from '@angular/core'; import { ENVIRONMENT_TOKEN } from '@reg/environment/domain'; @Injectable({ providedIn: 'root' }) export class RegStore extends ImmutableStore<TRegState> { #env = inject(ENVIRONMENT_TOKEN); constructor() { super({ name: 'RegistrationStore', mutationProducerFn: produce as unknown as MutationFn<TRegistrationState>, initialState: new RegState(), plugins: [ useStorePersistence({ persistenceKey: 'RegStore', persistenceStorage: localStorage, }), ] }); // 假设父类有addPlugins方法,在super之后再添加环境插件 this.addPlugins(this.#env.signalStoryStorePlugins); } store: Immutable<TRegState> = this.state(); }
这个方案的前提是父类支持动态扩展插件,如果没有这个能力,还是优先选择方案1。
备注:内容来源于stack exchange,提问作者st_clair_clarke
相关产品推荐
相关产品推荐

