Angular 5中构造函数参数初始化与new关键字的区别是什么?
Angular 5中构造函数参数注入与手动new实例化的核心区别
嘿,这个问题问到点子上了!在Angular生态里,这两种实例化类的方式有着本质的不同,我给你逐一拆解:
1. 实例创建的责任主体不同
- 构造函数参数注入:这是Angular依赖注入(DI)系统的核心用法。你只需要在构造函数里声明参数类型,Angular会自动帮你完成
exampleClass的实例创建,甚至会递归处理exampleClass内部的所有依赖(比如它如果依赖了HttpClient这类Angular服务)。你完全不用操心new这一步,框架会搞定一切。 - 手动new实例化:实例的创建完全由你自己负责。如果
exampleClass的构造函数需要传入参数(比如依赖其他服务),你得手动把这些依赖实例化并传进去,否则代码会直接报错。
2. 实例生命周期与管理方式不同
- DI注入的实例:Angular会根据你提供
exampleClass的层级(根模块、特性模块、组件)来管理实例的生命周期和作用域。比如如果exampleClass是根级提供的服务,那整个应用里只会存在一个单例实例;如果是组件级提供的,每个组件实例都会对应一个独立的exampleClass实例。Angular还会在合适的时机自动销毁这些实例,避免内存泄漏。 - 手动new的实例:生命周期完全由你掌控,Angular不会介入。你创建了实例,就得自己考虑什么时候销毁它,要是忘记清理(比如订阅的Observable没取消),很容易造成内存泄漏问题。
3. 依赖解析能力的差异
- DI注入的实例:能无缝享用Angular的依赖解析机制。比如
exampleClass如果依赖了Router、HttpClient等Angular内置服务,DI系统会自动把这些已经配置好的依赖注入进去,你不用做任何额外操作。 - 手动new的实例:
exampleClass内部的依赖需要你手动处理。比如如果exampleClass依赖HttpClient,你得自己写new exampleClass(new HttpClient()),但这样创建的HttpClient没有Angular的全局配置(比如拦截器、baseUrl),大概率会导致功能异常。
4. 测试友好度不同
- DI注入的方式:单元测试时特别方便,你可以用
TestBed轻松提供一个模拟的exampleClass实例,替换掉真实的实现,从而专注于测试组件本身的逻辑,不需要关心exampleClass内部的细节。 - 手动new的方式:要替换实例就很麻烦,要么修改组件代码,要么用一些不太优雅的hack手段,测试成本会高很多。
对应代码示例
代码1:构造函数参数注入
import { Component,OnInit } from '@angular/core'; import {exampleClass} from './exampleClass' @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { list: number[] = [1, 2, 3]; constructor(a:exampleClass) { a.hello(); } }
代码2:手动new实例化
import { Component,OnInit } from '@angular/core'; import {exampleClass} from './exampleClass' @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { list: number[] = [1, 2, 3]; private a: exampleClass; ngOnInit() { this.a = new exampleClass(); // 手动创建实例 this.a.hello(); } }
内容的提问来源于stack exchange,提问作者Amey
相关产品推荐
相关产品推荐

