如何在另一类构造函数中调用修改类实例变量,实现跨文件变更同步?
Alright, let's break down how to make this work properly. The core of your goal relies on working with the same class instance (thanks to dependency injection) and understanding how JavaScript handles value vs reference types.
1. First, Confirm Your Class is Registered as a Singleton
Most dependency injection frameworks (like Angular, NestJS, etc.) default to creating singleton instances for injected classes. This means every @inject() call will pull the exact same object instance—so changes to its properties will reflect everywhere it's used.
Here's your base class (e.g., MyInfoHolder.js):
export class MyInfoHolder { constructor(info) { this.info = info; } }
Make sure when registering this class with your DI container, it's set to singleton mode. For example, in Angular you'd add @Injectable({ providedIn: 'root' }) above the class; in other frameworks, check their docs for singleton registration.
2. Modify the Instance Correctly in the Injected File
When you inject the class in another file, you're referencing the same singleton instance. The critical thing here is to modify the internal properties of info (if it's a reference type like an object/array) instead of replacing the entire info variable.
Example injected file (e.g., UserEditor.js):
import { inject } from '@angular/core'; // Adjust based on your DI framework import { MyInfoHolder } from './MyInfoHolder'; export class UserEditor { private infoInstance = inject(MyInfoHolder); updateUserInfo() { // ✅ Good: Modify internal properties of the existing info object this.infoInstance.info.username = 'new_username_123'; this.infoInstance.info.isActive = true; // ❌ Bad: Replaces the entire info reference (breaks sync for old references) // this.infoInstance.info = { username: 'new_username' }; } }
3. What If info Is a Value Type?
If info is a primitive value (string, number, boolean), direct reassignment will break sync because primitives are passed by value. Fix this by wrapping the primitive in an object in your class constructor:
// Updated MyInfoHolder class export class MyInfoHolder { constructor(info) { // Wrap primitive value in an object to maintain reference this.info = { value: info }; } } // Then modify it like this in the injected file: this.infoInstance.info.value = 'updated_primitive_value';
4. Handling Non-Singleton Scenarios
If your DI setup creates a new instance every time you inject the class (multi-instance mode), the above approach won't work. In this case, use a shared state management approach:
- Create a separate state service that holds the
infovalue - Have your original class and injected code subscribe to this service's state
- Update the state via the service, and all subscribers will get the latest value
Example state service approach:
// Shared state service export class InfoStateService { private currentInfo = { username: 'initial_user' }; // Use a subject if you need reactive updates (e.g., RxJS BehaviorSubject) getInfo() { return this.currentInfo; } updateInfo(newInfo) { Object.assign(this.currentInfo, newInfo); } } // Updated MyInfoHolder class export class MyInfoHolder { constructor(private infoState: InfoStateService) { this.info = this.infoState.getInfo(); } } // Injected file update export class UserEditor { private infoState = inject(InfoStateService); updateUserInfo() { this.infoState.updateInfo({ username: 'updated_via_state' }); } }
内容的提问来源于stack exchange,提问作者vascobento

