MST

星途 面试题库

面试题:Angular依赖注入器的作用域机制及其对服务实例化的影响是什么?

详细阐述Angular依赖注入器不同作用域(如根作用域、组件作用域等)的工作原理,以及这些作用域如何影响服务的实例化过程,包括何时创建新实例,何时复用已有实例等,结合具体代码示例说明。
37.7万 热度难度
前端开发Angular

知识考点

AI 面试

面试题答案

一键面试

根作用域

  1. 工作原理:根作用域是应用级别的作用域,整个应用只有一个根注入器。所有在根作用域注册的服务,在整个应用中是单例的。无论在应用的哪个组件中注入该服务,都将获得同一个实例。
  2. 对服务实例化的影响
    • 创建新实例:当应用启动,首次有组件尝试注入在根作用域注册的服务时,会创建该服务的新实例。
    • 复用已有实例:后续任何组件注入该服务,都会复用启动时创建的那个实例。
    • 代码示例
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class RootScopedService {
  private data: string = 'Initial data in root scoped service';

  getData() {
    return this.data;
  }

  setData(newData: string) {
    this.data = newData;
  }
}

在组件中使用:

import { Component } from '@angular/core';
import { RootScopedService } from './root - scoped.service';

@Component({
  selector: 'app - root',
  templateUrl: './app.component.html'
})
export class AppComponent {
  constructor(private rootScopedService: RootScopedService) {
    console.log(this.rootScopedService.getData());
    this.rootScopedService.setData('New data in app component');
  }
}

在另一个组件中:

import { Component } from '@angular/core';
import { RootScopedService } from './root - scoped.service';

@Component({
  selector: 'app - another - component',
  templateUrl: './another - component.html'
})
export class AnotherComponent {
  constructor(private rootScopedService: RootScopedService) {
    console.log(this.rootScopedService.getData()); // 会输出 'New data in app component'
  }
}

组件作用域

  1. 工作原理:每个组件都有自己的注入器,组件作用域的服务仅在该组件及其子组件内有效。如果一个服务在组件中注册,那么这个组件及其子组件会创建和使用该服务的独立实例,与其他组件使用的实例相互隔离。
  2. 对服务实例化的影响
    • 创建新实例:当组件初始化且首次尝试注入在该组件作用域注册的服务时,会创建新实例。
    • 复用已有实例:在该组件及其子组件内,后续注入该服务会复用这个组件作用域内创建的实例。但与其他组件的同类型服务实例不共享。
    • 代码示例
import { Injectable } from '@angular/core';

@Injectable()
export class ComponentScopedService {
  private data: string = 'Initial data in component scoped service';

  getData() {
    return this.data;
  }

  setData(newData: string) {
    this.data = newData;
  }
}

在组件中注册并使用:

import { Component } from '@angular/core';
import { ComponentScopedService } from './component - scoped.service';

@Component({
  selector: 'app - component - scope - demo',
  templateUrl: './component - scope - demo.html',
  providers: [ComponentScopedService]
})
export class ComponentScopeDemoComponent {
  constructor(private componentScopedService: ComponentScopedService) {
    console.log(this.componentScopedService.getData());
    this.componentScopedService.setData('New data in component - scope - demo component');
  }
}

在子组件中:

import { Component } from '@angular/core';
import { ComponentScopedService } from './component - scoped.service';

@Component({
  selector: 'app - sub - component',
  templateUrl: './sub - component.html'
})
export class SubComponent {
  constructor(private componentScopedService: ComponentScopedService) {
    console.log(this.componentScopedService.getData()); // 会输出 'New data in component - scope - demo component'
  }
}

如果在另一个组件中使用同样的 ComponentScopedService,由于不在同一个组件作用域,会创建新的实例,与 ComponentScopeDemoComponent 中的实例相互独立。